React Router v4 - Switch 不适用于路由渲染
React Router v4 - Switch doesn't work with route render
我正在使用 React Router 来显示相同的组件,但在每个路由上使用不同的道具:
<BrowserRouter>
<div>
<Route exact path="/" render={() => LOGGED_IN ? <Redirect to="/profile" /> : <Login />} />
<Route path="/profile/:id" render={(props) => <App {...props} page="profile" pageLadder={['Home', 'Profile']} />}/>
<Route path="/team" render={() => <App page="team" pageLadder={['Home', 'Team']} />}/>
<Route path="/transactions" render={() => <App page="transactions" pageLadder={['Home', 'Transactions']} />}/>
<Route path="/tournaments" render={() => <App page="tournaments" pageLadder={['Home', 'Tournaments']} />}/>
<Route path="/tournament/:id" render={(props) => <App {...props} page="tournament" pageLadder={['Home', 'Tournament', props.match.params.id]} />}/>
<Route path="/match/:id" render={(props) => <App {...props} page="match" pageLadder={['Home', 'Match', props.match.params.id]} />} />
<Route path="/scrims" render={() => <App page="scrims" pageLadder={['Home', 'Scrims']} />} />
<Route path="/faq" render={() => <App page="faq" pageLadder={['Home', 'FAQ']} />} />
<Route path="/staff" render={() => <App page="staff" pageLadder={['Home', 'Staff']} />} />
<Route path="/privacy" render={() => <App page="privacy" pageLadder={['Home', 'Privacy Policy']} />} />
<Route path="/tos" render={() => <App page="tos" pageLadder={['Home', 'Terms of Service']} />} />
</div>
</BrowserRouter>
我还需要捕获 404 错误,所以我添加了 Switch
和 <Route component={NotFound} />
:
<BrowserRouter>
<Switch>
<Route exact path="/" render={() => LOGGED_IN ? <Redirect to="/profile" /> : <Login />} />
... more routes
<Route component={NotFound} />
</Switch>
</BrowserRouter>
404 确实有效,但每个 <Link>
元素都停止工作 - 单击后,url 确实发生了变化,但组件保持不变,除非我刷新站点。
我尝试将我的代码更改为此以进行测试:
<BrowserRouter>
<Switch>
<Route path="/team" component={Login} />
<Route path="/profile/" component={App} />
</Switch>
</BrowserRouter>
使用此代码,<Link>
组件确实按预期工作。
我该怎么做才能使我的第一个代码按预期工作?
来自您的代码示例:
class App extends Component {
constructor(props){
super(props);
// appStore is an instance of react-easy-state library
// App component puts the components together, the actual pages are in AppMain component (look below for code)
appStore.changePage(this.props.page, this.props.pageLadder, this.props.match ? this.props.match.params.id : -1);
// this function changes appStore.page.name value and it's a global type store
}
render() {
return (
<div>
<div>
<Sidebar />
<AppMain />
</div>
</div>
);
}
}
您正在 构造函数 中调用 appStore.changePage
,它只会在第一次初始化组件时被调用一次。即使您在多个路由上都有组件,当您更改路由和 props 时它也不会被卸载,这意味着构造函数永远不会被再次调用。
您需要做的是在您的 props 更改时使用 componentDidUpdate
更改页面:
componentDidUpdate (prevProps, prevState) {
if(prevProps.page !== this.props.page) {
appStore.changePage(this.props.page, this.props.pageLadder, this.props.match ? this.props.match.params.id : -1);
}
}
现在,你比较当前道具的prevProps
,如果page
道具发生变化,你需要再次触发appStore.changePage
。现在,我不确定 appStore.changePage
在做什么,所以我不确定您是否也需要更新 <AppMain />
,但这应该会让您走上正轨。
我正在使用 React Router 来显示相同的组件,但在每个路由上使用不同的道具:
<BrowserRouter>
<div>
<Route exact path="/" render={() => LOGGED_IN ? <Redirect to="/profile" /> : <Login />} />
<Route path="/profile/:id" render={(props) => <App {...props} page="profile" pageLadder={['Home', 'Profile']} />}/>
<Route path="/team" render={() => <App page="team" pageLadder={['Home', 'Team']} />}/>
<Route path="/transactions" render={() => <App page="transactions" pageLadder={['Home', 'Transactions']} />}/>
<Route path="/tournaments" render={() => <App page="tournaments" pageLadder={['Home', 'Tournaments']} />}/>
<Route path="/tournament/:id" render={(props) => <App {...props} page="tournament" pageLadder={['Home', 'Tournament', props.match.params.id]} />}/>
<Route path="/match/:id" render={(props) => <App {...props} page="match" pageLadder={['Home', 'Match', props.match.params.id]} />} />
<Route path="/scrims" render={() => <App page="scrims" pageLadder={['Home', 'Scrims']} />} />
<Route path="/faq" render={() => <App page="faq" pageLadder={['Home', 'FAQ']} />} />
<Route path="/staff" render={() => <App page="staff" pageLadder={['Home', 'Staff']} />} />
<Route path="/privacy" render={() => <App page="privacy" pageLadder={['Home', 'Privacy Policy']} />} />
<Route path="/tos" render={() => <App page="tos" pageLadder={['Home', 'Terms of Service']} />} />
</div>
</BrowserRouter>
我还需要捕获 404 错误,所以我添加了 Switch
和 <Route component={NotFound} />
:
<BrowserRouter>
<Switch>
<Route exact path="/" render={() => LOGGED_IN ? <Redirect to="/profile" /> : <Login />} />
... more routes
<Route component={NotFound} />
</Switch>
</BrowserRouter>
404 确实有效,但每个 <Link>
元素都停止工作 - 单击后,url 确实发生了变化,但组件保持不变,除非我刷新站点。
我尝试将我的代码更改为此以进行测试:
<BrowserRouter>
<Switch>
<Route path="/team" component={Login} />
<Route path="/profile/" component={App} />
</Switch>
</BrowserRouter>
使用此代码,<Link>
组件确实按预期工作。
我该怎么做才能使我的第一个代码按预期工作?
来自您的代码示例:
class App extends Component {
constructor(props){
super(props);
// appStore is an instance of react-easy-state library
// App component puts the components together, the actual pages are in AppMain component (look below for code)
appStore.changePage(this.props.page, this.props.pageLadder, this.props.match ? this.props.match.params.id : -1);
// this function changes appStore.page.name value and it's a global type store
}
render() {
return (
<div>
<div>
<Sidebar />
<AppMain />
</div>
</div>
);
}
}
您正在 构造函数 中调用 appStore.changePage
,它只会在第一次初始化组件时被调用一次。即使您在多个路由上都有组件,当您更改路由和 props 时它也不会被卸载,这意味着构造函数永远不会被再次调用。
您需要做的是在您的 props 更改时使用 componentDidUpdate
更改页面:
componentDidUpdate (prevProps, prevState) {
if(prevProps.page !== this.props.page) {
appStore.changePage(this.props.page, this.props.pageLadder, this.props.match ? this.props.match.params.id : -1);
}
}
现在,你比较当前道具的prevProps
,如果page
道具发生变化,你需要再次触发appStore.changePage
。现在,我不确定 appStore.changePage
在做什么,所以我不确定您是否也需要更新 <AppMain />
,但这应该会让您走上正轨。