我似乎无法弄清楚如何使用路由参数/ ownProps加载组件/对象我的配置基本上与react redux应用程序的标准相同,我的actions / reducers工作正常但是对于此组件数据未预先加载。我假设这意味着在定义它之前尝试使用'user'对象时会发生竞争。我假设这是因为它偶尔会起作用 - 它通过reducer(s)和api调用 - 结果看起来很好。我是否应该首先创建默认的“用户”对象?
路线看起来像
[tld]/user/1234
组件
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as userActions from '../../actions/userActions';
import User from './User';
class UserPage extends Component{
constructor(props, context){
super(props, context);
}
componentDidMount(){
this.fetchData();
}
fetchData(){
const {userId} = this.props;
const {fetchUser} = this.props.actions;
fetchUser(userId);
}
render(){
// This component when rendered has undefined property exceptions
// though sometimes it works :)
return(<User user={this.props.currentUser} />);
}
}
function mapStateToProps(state, ownProps){
return {
currentUser: state.user,
userId: ownProps.params.id
}
}
function mapDispatchToProps(dispatch){
return {
actions: bindActionCreators(userActions, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(UserPage);
更新 所以我想出了一个丑陋的方法来解决这个问题在渲染
return (
{Object.keys(this.props.currentUser).length > 0 ?
<User user={this.props.currentUser} /> ? null }
)
这不是正确的方法。 - 另外我注意到,如果我只是更改路由ID,那么在等待api调用的延迟返回新用户时,会有一个以前加载的用户的短暂闪存...对不起react / redux对我来说是相当新的
答案 0 :(得分:2)
有办法避免未定义的道具:
1 在用户缩减器中定义初始状态
const initialState = { user:'', ... };
const user = (state = initialState, action) => {...};
export default user;
2 使用state.user||""
const mapStateToProps = (state, ownProps) =>({
currentUser: state.user||"",
userId: ownProps.params.id
});
3 有时需要在加载数据之前不允许安装组件。
const LoadingBlock = props => {
return (<div>{props.isLoading ? 'loading...' : props.children}</div>);
};
LoadingBlock.defaultProps = {
isLoading: true
};
///then wrap component that will be loading
<LoadingBlock isLoading={this.props.isLoading}>
<UserComponent user={this.props.user}>
</LoadingBlock>
4 如果this.props.user未定义,则不显示userComponent
render(){
let {user} = this.props
return(
<div>{user && <UserComponent user={user}>}</div>
)
}
5 如果this.props.user未定义,则显示组件,否则显示一些&#34;内容&#34;
render(){
let {user} = this.props
return(
<div>{user ? <UserComponent user={user}> : "loading"}</div>
)
}
6 定义默认道具
class Control extends React.Component {...}
Control.defaultProps = {value: "somevalue"};
答案 1 :(得分:1)
我能想到的一些事情:
检查this.props.currentUser
是否定义实际上是个好主意,但我会使用这种语法:
const { currentUser } = this.props;
return currentUser && <User user={currentUser} />;
仅在将组件添加到DOM时调用componentDidMount。因此,如果UserPage组件已经在DOM中,它将不会触发,并且永远不会调用您的提取代码。在这种情况下,您可以使用componentWillReceiveProps
事件来评估新道具。 (参见:https://facebook.github.io/react/docs/component-specs.html了解更多信息)
fetchUser
到底做了什么?我假设它是一个异步调用来获取用户数据。你在使用像redux-thunk这样的中间件吗?该代码看起来如何?
如果您正在使用Thunk,则可以调度多个操作以指示获取的状态。所以,像这样:
export function fetchUser(userId) {
return dispatch => {
dispatch(fetchUserStart());
someService.fetchUser(userId)
.then(user => dispatch(fetchUserDone(user)))
.catch(error => {
dispatch(fetchUserError(error));
});
};
}
在上面的代码fetchUserStart
中,fetchUserDone
和fetchUserError
都是影响用户状态的所有操作(此处未显示的代码)。 fetchUserStart
可以将用户状态设置为undefined,而fetchUserDone
将其设置为您从异步提取获得的用户。当您的UserPage组件连接到此状态时,它将通过显示/不显示用户组件来做出反应。