我已经将我的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));
3条答案
按热度按时间vfwfrxfs1#
首先,检查该值是否可用,
您可以执行以下操作来解决该错误:
出版日期:
用户道具可能从某个API初始化或在某个进程之后初始化,因此第一次渲染时它不可用,但一旦道具发生变化(您的用户已初始化),它就会强制重新渲染,因此您可以在第二次获得数据。
vyswwuz22#
在接收到的错误中,当使用Fetch从API接收数据时,它接收的数据为空值,并且由于无法接收数据而无法读取。为防止这种情况,将使用条件(&&)检查要列出的数据。
ldxq2e6h3#
在表单中,您应给予name=“Image”,并且应在www.example.com中传递相同的名称router.post