我有一个表示页面的React组件。用户永远不应该到达页面,除非他们有一些状态。如果缺少状态,我写了以下内容让react-router
重定向用户:
class BoxScreen extends Component {
constructor(props) {
super(props);
if (Object.keys(this.props.boxState.current).length === 0) {
browserHistory.push('/secured/find')
}
然后我收到这条消息:
warning.js:36警告:setState(...):无法在现有状态转换期间更新(例如在
render
或其他组件的构造函数中)。渲染方法应该是道具和状态的纯函数;构造函数副作用是反模式,但可以移动到componentWillMount
。
好的,我将我的重定向代码移到componentWillMount
:
class BoxScreen extends Component {
...
componentWillMount() {
if (Object.keys(this.props.boxState.current).length === 0) {
browserHistory.push('/secured/find')
}
}
render() {
// Don't want this executed or else I'll need to pollute it with null guards...
}
}
然而,问题在于上述内容并未阻止render
被调用,这绝对不是必需的。放置这个的最合适的位置在哪里,我可以使组件渲染短路并执行重定向?
答案 0 :(得分:1)
您可以使用react-router的onEnter
道具来实现这一目标:
function checkAuthenticated(nextState, replace) {
if (!SOME_CONDITION) {
replace('/secured/find')
}
}
<Route ... onEnter={checkAuthenticated} />
但我相信你不能以这种方式访问组件道具。您必须以其他方式跟踪状态。如果您使用的是Redux,我相信您可以使用redux-router来获取商店。
答案 1 :(得分:1)
只需在渲染中使用react-router
的{{1}}组件来实现它,我正在使用v4,因此我将为您提供与之兼容的解决方案。
<Redirect/>
将import {Redirect} from 'react-router-dom';
class BoxScreen extends Component {
...
render() {
return this.props.condition ?
<ActualComponent /> : <Redirect to="/someGuardLink">;
}
}
替换为您的组件JSX,是的,这应该可行。您的组件仍然会挂载和渲染,但之后它会将您重定向到其他链接,而不会发现它的任何影响。这是正式的做法。
答案 2 :(得分:0)
扩展smishr4的内容:
ID: -1
function mapStateToProps(state, ownProps) {
return {
ID: state.ID,
}
}
componentWillMount() {
{
if (this.props.ID != -1 && this.props.ID != undefined) {
this.props.loadYourDataFromAPIGivenID(this.props.ID);
}
else {
this.props.history.push('/');
}
}
}
有更好的方法吗?大概。您也许可以直接在路由器内进行阻塞,但这是一个很好的解决方法。
您也可以直接使用this.state ,但是this.props使用起来更安全。