关于如何将React Router的history.push('/route')
与Redux
一起使用,我有点无能为力。
换句话说,如果您使用Redux的mapDispatchToProps
连接组件,那么如何在调度某个操作后放置应该被触发的history.push('/route')
?
为了澄清这个问题,这里有一个我的实验片段......
class PostContainer extends React.Component {
handleSubmit(data) {
return this.props.addPost(data);
}
render() {
return (<Post onSubmit={data=> this.handleSubmit(data)}/>);
}
}
const mapDispatchToProps = (dispatch) => {
return {
addPost: (data) => {
dispatch(addPost(data)).data.then((result) => {
dispatch(addPostFulfilled(result.data));
//How do you call the following function?
this.props.history.push('/posts')
}).catch((error) => {
dispatch(addPostRejected());
});
},
}
}
export default connect(null, mapDispatchToProps)(PostContainer);
正如您所看到的,只要帖子通过addPostFulfilled
添加到Redux的状态,页面就需要通过history.push移至/posts
。
根据Redux的文档,容器用于更新状态(以及获取数据)。所以,愚蠢的组件不应该像history.push
那样放置。
比上面的代码更好的方法是什么?
任何建议都将受到赞赏。
答案 0 :(得分:3)
您可以使用用户react-router-redux(需要初始设置)并从动作创建者发送您的操作
import { push } from 'react-router-redux'
class PostContainer extends React.Component {
handleSubmit(data) {
return this.props.addPost(data);
}
render() {
return (
<div>
<Post onSubmit={data=> this.handleSubmit(data)}/>
</div>
);
}
}
const mapDispatchToProps = (dispatch) => {
return {
addPost: (data) => {
dispatch(addPost(data)).data.then((result) => {
dispatch(addPostFulfilled(result.data));
//How do you call the following function?
dispatch(push('/posts'));
}).catch((error) => {
dispatch(addPostRejected());
});
},
}
}
export default connect(null, mapDispatchToProps)(PostContainer);
或者只是将push作为“完成回调”传递。
class PostContainer extends React.Component {
handleSubmit(data, done) {
return this.props.addPost(data, done);
}
render() {
const { push } = this.props.history;
return (
<div>
<Post onSubmit={data=> this.handleSubmit(data, push)}/>
</div>
);
}
}
const mapDispatchToProps = (dispatch) => {
return {
addPost: (data, done) => {
dispatch(addPost(data)).data.then((result) => {
dispatch(addPostFulfilled(result.data));
//How do you call the following function?
done('/posts')
}).catch((error) => {
dispatch(addPostRejected());
});
},
}
}
export default connect(null, mapDispatchToProps)(PostContainer);
答案 1 :(得分:0)
const mapDispatchToProps = (dispatch) => {
return {
addPost: (data) => {
dispatch(addPost(data)).data.then((result) => {
dispatch(addPostFulfilled(result.data));
<!-- removed from here -->
}).catch((error) => {
dispatch(addPostRejected());
});
},
}
}
,即
addPostFulFilled
完成this.history.push('/route')
数据后,您可以选择在组件中执行props
。您可以执行componentWillReceiveProps
更新时调用的任何生命周期方法。
也许,将其添加到class PostContainer extends React.Component {
componentWillReceiveProps(nextProps){
/*Added here*/
if(nextProps.someFlag){ this.props.history.push('/someRoute');
}}
。
store
请注意,上述内容仅适用于
react-router-4
跟踪位置更改。(Read More)withRouter
,在这种情况下,您将使用PostContainer
包裹您的连接,这将使历史对象在shouldComponentUpdate
中作为道具出现。react-router-redux
中编写必要的逻辑。如果上述内容听起来像是一大堆乱码,您可以随时使用push
的{{1}} API,以便在浏览器历史记录中推送新条目。您可以在您选择的任何地方导入,只需推送新路线。
详细信息可以在react-router-redux github pages中看到并引用文档
push和replace都包含一个位置描述符,它可以是一个 描述URL的对象或纯字符串URL。这些动作创作者 也可以作为routerActions在一个对象中使用 在使用Redux的bindActionCreators()时可以方便地使用。
因此,请直接使用mapDispatchToProps中的history.push()
,或将其作为道具传递给PostContainer
反应组件中使用。
答案 2 :(得分:0)
更清洁的方法可能是使用React Router的<Redirect>
:
class PostContainer extends React.Component {
render() {
if (userJustAddedAPostRightNow === true) {
return <Redirect to='/posts' />
}
return (
<div>
<Post onSubmit={addPost}/>
</div>
);
}
}
export default connect(null, { addPost })(PostContainer);
addPost
如果成功将触发状态更改。它应该将userJustAddedAPostRightNow
更改为true,以便将您重定向到帖子的页面。
要避免所有这些嵌套的回调,可以遵循Nir Kaufman's approach并处理中间件中的逻辑:
//src/middlewares/post.js
export const newPost = ({dispatch}) => next => action => {
next(action);
if (action.type === ADD_POST) {
dispatch(apiRequest('POST', action.URL, null, ADD_POST_SUCCESS, ADD_POST_ERROR));
dispatch(showSpinner());
}
};
然后,如果成功,ADD_POST_SUCCESS
动作将通过减速器更改userJustAddedAPostRightNow
的值。