redux TypeError:无法读取null的属性'image'

2izufjch  于 2022-11-12  发布在  其他
关注(0)|答案(3)|浏览(388)

我已经将我的ProfileComponent.js与redux存储连接,然后使用该状态呈现用户图像,但是当我刷新页面时,我得到了这个TypeError,并且当我进行控制台检查时,我的组件似乎在作为属性可用之前使用了用户状态(它在Profile属性中基本上是空的),但这不应该发生,对吗?

错误

当我省略了<img />元素时,我的个人资料似乎被渲染了两次,第一次我的用户为空,第二次我的用户在道具中被更新。有人能给我解释一下发生了什么吗?

主控台

配置文件组件.js

import React, { Component } from 'react';
import {  Container, Row, Col, Card, CardHeader, CardBody, CardFooter, Input, Form, Button } from 'reactstrap';
import {connect} from 'react-redux';
import { uploadImage, fetchUser } from '../redux/ActionCreators';
import { baseUrl } from '../config';
import { Switch, Route, withRouter, Redirect } from 'react-router-dom';

const mapStateToProps = (state) => {
    return {
        user: state.auth.user,

    }
}

const mapDispatchToProps = (dispatch) => ({
    uploadImage: (userId, imageData) => {dispatch(uploadImage(userId, imageData))},
    fetchUser: (userId) => {dispatch(fetchUser(userId))}
})

class Profile extends Component {
    constructor(props){
        super(props);
        this.state = {
            selectedFile: null
        }
        this.handleUpload = this.handleUpload.bind(this);
        this.onChangeHandler = this.onChangeHandler.bind(this);
    }

    handleUpload(event){
        const data = new FormData() 
        data.append('image', this.state.selectedFile)
        this.props.uploadImage(this.props.match.params.userId, data);
        event.preventDefault();
    }
    onChangeHandler=event=>{
        this.setState({selectedFile: event.target.files[0]});
    }
    componentDidMount() {
        console.log('user',this.props.user);
    }

    render() {
        //
        return(
            <Container className="form-container" >
                <Row>
                    <Col md={{size:6}}>
                        <Col md={{size:6,offset:3}}>
                            <div  style={{marginBottom:30}}> 
                                <img className="profile-image" src= {`${baseUrl}${this.props.user.image}`}/>
                                <Form >
                                    <Input type="file" name="image"  id="file" onChange={this.onChangeHandler} />
                                    <Button type="submit" color="primary" className="form-control" onClick = {this.handleUpload}>Upload</Button>
                                </Form>
                            </div>
                        </Col>
                    </Col>
                    <Col md={6}>
                        <div className="shadow-container" style={{marginTop:0}}>
                        <Card>
                            <CardHeader>
                                <h2>Profile details</h2>
                            </CardHeader>
                            <CardBody>
                                <h4 style={{color:'grey'}}>{this.props.match.params.userId}</h4>
                                <h5 style={{color:'grey'}}></h5>
                                <small><i></i></small>
                            </CardBody>
                            <CardFooter>
                                <Row>
                                    <Col>
                                        <a href="/editprofile"><span className="fa fa-pencil fa-2x ml-auto" 
                                            style={{color:'blue', display:'flex',
                                             flexDirection:'row',justifyContent:'flex-end'}}></span></a>
                                    </Col>
                                    <Col>
                                        <a href="/deleteprofile"><span className="fa fa-trash fa-2x" style={{color:'red'}}></span></a>
                                    </Col>
                                </Row>
                            </CardFooter>
                        </Card>
                        </div>
                    </Col>
                </Row>
            </Container>
        );
    }
}

export default withRouter(connect(mapStateToProps,mapDispatchToProps)(Profile));

主组件.js

import React, {Component} from 'react';
import  Menu  from './MenuComponent';
import Home from './HomeComponent';
import Users from './UsersComponent';
import Register from './RegisterComponent';
import Signin from './SigninComponent';
import Profile from './ProfileComponent';
import Edit from './EditComponent';
import { signin, signout, fetchUser } from '../redux/ActionCreators';
import {connect} from 'react-redux';
import { Switch, Route, withRouter, Redirect } from 'react-router-dom';
import { CSSTransition, TransitionGroup } from 'react-transition-group'

const mapStateToProps = (state) => {
    return {
        auth: state.auth
    }
}

const mapDispatchToProps = (dispatch) => ({
    signin: (credentials) => {dispatch(signin(credentials))},
    signout: () => {dispatch(signout())},
    fetchUser: (userId) => {dispatch(fetchUser(userId))}
})

class Main extends Component {

    componentDidMount() {
        this.props.fetchUser(this.props.auth.userId);

        console.log('main',this.props.auth);
    }

    render() {

        const PrivateRoute = ({ component: Component, ...rest }) => (
            <Route {...rest} render={(props) => (
              this.props.auth.authenticated
                ? <Component {...props} />
                : <Redirect to={{
                    pathname: '/signin',
                    state: { from: props.location }
                  }} authenticated={this.props.auth.authenticated} />
            )} />
          )
        return (
            <div>
                <Menu authenticated={this.props.auth.authenticated} signout={this.props.signout} userId={this.props.auth.userId}/>
                <TransitionGroup>
                    <CSSTransition key={this.props.location.key} classNames="page" timeout={300}>
                <Switch>
                    <Route path="/home" component={Home} />
                    <PrivateRoute path="/users" component={Users} />
                    <Route path="/signup" component={Register} />
                    <Route path="/signin" component={() => <Signin signin={this.props.signin} authenticated={this.props.auth.authenticated}/>} />} />
                    <PrivateRoute path="/profile/:userId" component={() => <Profile />} /> 
                    <Route path="/editprofile" component={Edit} />  
                    <Redirect to="/home" />  
                </Switch>
                </CSSTransition>
                </TransitionGroup>
            </div>
        );
    }
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Main));
vfwfrxfs

vfwfrxfs1#

首先,检查该值是否可用,
您可以执行以下操作来解决该错误:

{this.props.user && <img className="profile-image" src= {`${baseUrl}${this.props.user.image}`}/> }

出版日期:

用户道具可能从某个API初始化或在某个进程之后初始化,因此第一次渲染时它不可用,但一旦道具发生变化(您的用户已初始化),它就会强制重新渲染,因此您可以在第二次获得数据。

vyswwuz2

vyswwuz22#

在接收到的错误中,当使用Fetch从API接收数据时,它接收的数据为空值,并且由于无法接收数据而无法读取。为防止这种情况,将使用条件(&&)检查要列出的数据。

{user && <div style={{display : 'flex', flex-direction : 'row', justify-content :'center', width : '100%'}}>
            <div style={{width :'60%'}}>
                <img style={{width : '%90',}} src={user.images[1]} alt={user.title}/>
            </div>
            <div>
                <h1 style={{fontSize :'48px' , font-weight : 'bold'}} >{user.title} </h1>
                <h2 style={{fontSize :'36px'}}> {user.brand}</h2>
                <h2 style={{fontSize :'36px'}}>Discount: {user.discountPercentage}</h2>
                <h2 style={{fontSize :'36px'}}>Price: {user.price}</h2>
                <h6 style={{fontSize :'24px'}}>Stock: {user.stock}</h6>
            </div>
           </div>}
ldxq2e6h

ldxq2e6h3#

在表单中,您应给予name=“Image”,并且应在www.example.com中传递相同的名称router.post

相关问题