我遇到了一个包含某些必需propTypes的组件的问题。
我得到的错误是:
Warning: Failed prop type: The prop `firstname` is marked as required in `UserHeader`, but its value is `undefined`.
in UserHeader (at App.js:32)
in App (created by Connect(App))
in Connect(App) (at index.js:17)
in Provider (at index.js:16)
我的代码......
import React, { Component } from 'react';
import { connect } from 'react-redux';
import ErrorBoundary from './containers/ErrorBoundary'
import UserHeader from './components/UserHeader';
import Header from './components/Header';
class App extends Component {
constructor(props) {
super(props);
}
componentWillMount() {
// Pretend this is an API call that takes a second
setTimeout(() => {
const data = {
user: {
firstname: 'bughunter',
level: 55
}
};
this.props.didMountHandler(data)
}, 1000);
}
render() {
return (
<ErrorBoundary>
<Header />
<UserHeader
firstname={this.props.firstname}
level={this.props.level}
/>
</ErrorBoundary>
);
}
}
const mapStateToProps = (state, ownProps) => {
return {
firstname: state.user.firstname,
level: state.user.level
}
};
const mapDispatchToProps = dispatch => ({
didMountHandler: data => {
dispatch({
type: 'USER_DATA_RECEIVED',
data
});
}
})
const AppContainer = connect(
mapStateToProps,
mapDispatchToProps
)(App);
export default AppContainer;
我在render
方法调用之前修改了状态,所以我很困惑UserHeader
完成之前检查setTimeout
的道具是什么?
在setTimeout
完成之前,我怎样才能推迟渲染/ propChecking?
我考虑过在创建商店时设置一些初始默认状态,如下所示:
{
user: {
firstname: '',
level: 0
}
}
......但这看起来有些过时。
答案 0 :(得分:3)
您没有修改render
之前的状态,因为您正在使用setTimeout。渲染不等待您的setTimeout
,并在调用componentWillMount
后直接调用。
您必须在redux reducer中设置一些默认值。你可以在减速器中设置
user: null,
....
并在渲染时检查您是否拥有该用户
render() {
const { user } = this.props;
{ user && <UserHeader firstname={user.firstname} level={user.level} /> }
在mapStateToProps
中只需复制整个user
obj:
const mapStateToProps = (state, ownProps) => {
return {
user: state.user
}
};
还有其他方法可以做到这一点。您可以按照建议在reducer中设置firstName
和level
的默认值,也可以始终使用UserHeader
道具渲染user
并确定如果您没有设置值subValues,则显示。
答案 1 :(得分:0)
添加一个加载程序组件或null,如下所示。并使用当地的州。
state = { initialized: false }
componentWillMount() {
// Pretend this is an API call that takes a second
setTimeout(() => {
const data = {
user: {
firstname: 'bughunter',
level: 55
}
};
this.props.didMountHandler(data)
this.setState({ initialized: true });
}, 1000);
}
render(){
if(!this.state.initialized){
return null;
}
return (
<ErrorBoundary>
<Header />
<UserHeader
firstname={this.props.firstname}
level={this.props.level}
/>
</ErrorBoundary>
);
}