【发布时间】:2021-01-24 13:25:08
【问题描述】:
将 React 与 React Router 一起使用时,我遇到了一些安装问题。 这甚至可能不是 React Router 本身的问题。 我想与子路由一起传递一些额外的数据。 这似乎有效,但是主页上的更改会在每次状态更改时触发孙子重新挂载。
为什么会这样?为什么这只会发生在孙辈身上而不仅仅是孩子们身上?
代码示例:
import React, { useEffect, useState } from 'react';
import { Route, Switch, BrowserRouter as Router, Redirect } from 'react-router-dom';
const MainPage = ({ ChildRoutes }) => {
const [foo, setFoo] = useState(0);
const [data, setData] = useState(0);
const incrementFoo = () => setFoo(prev => prev + 1);
useEffect(() =>{
console.log("mount main")
},[]);
useEffect(() =>{
setData(foo * 2)
},[foo]);
return (
<div>
<h1>Main Page</h1>
<p>data: {data}</p>
<button onClick={incrementFoo}>Increment foo {foo}</button>
<ChildRoutes foo={foo} />
</div>
);
};
const SecondPage = ({ ChildRoutes, foo }) => {
const [bar, setBar] = useState(0);
const incrementBar = () => setBar(prev => prev + 1);
useEffect(() =>{
console.log("mount second")
},[]);
return (
<div>
<h2>Second Page</h2>
<button onClick={incrementBar}>Increment bar</button>
<ChildRoutes foo={foo} bar={bar} />
</div>
);
};
const ThirdPage = ({ foo, bar }) => {
useEffect(() =>{
console.log("mount third")
},[]);
return (
<div>
<h3>Third Page</h3>
<p>foo: {foo}</p>
<p>bar: {bar}</p>
</div>
);
};
const routingConfig = [{
path: '/main',
component: MainPage,
routes: [
{
path: '/main/second',
component: SecondPage,
routes: [
{
path: '/main/second/third',
component: ThirdPage
},
]
}
]
}];
const Routing = ({ routes: passedRoutes, ...rest }) => {
if (!passedRoutes) return null;
return (
<Switch>
{passedRoutes.map(({ routes, component: Component, ...route }) => {
return (
<Route key={route.path} {...route}>
<Component {...rest} ChildRoutes={props => <Routing routes={routes} {...props}/>}/>
</Route>
);
})}
</Switch>
);
};
export const App = () => {
return(
<Router>
<Routing routes={routingConfig}/>
<Route exact path="/">
<Redirect to="/main/second/third" />
</Route>
</Router>
)
};
export default App;
MainPage 中的每个单独状态更改都会导致 ThirdPage 被重新挂载。
由于 React Router,我无法使用 StackOverflow 创建 sn-p。所以这里有一个完全相同的代码框:https://codesandbox.io/s/summer-mountain-unpvr?file=/src/App.js
预期行为是每个页面只触发一次安装。 我知道我可以通过使用 Redux 或 React.Context 来解决这个问题,但现在我想知道是什么导致了这种行为以及是否可以避免。
===========================
更新: 使用 React.Context 它可以工作,但我想知道如果没有它是否可以做到这一点?
工件:
const ChildRouteContext = React.createContext();
const ChildRoutesWrapper = props => {
return (
<ChildRouteContext.Consumer>
{ routes => <Routing routes={routes} {...props} /> }
</ChildRouteContext.Consumer>
);
}
const Routing = ({ routes: passedRoutes, ...rest }) => {
if (!passedRoutes) return null;
return (
<Switch>
{passedRoutes.map(({ routes, component: Component, ...route }) => {
return (
<Route key={route.path} {...route}>
<ChildRouteContext.Provider value={routes}>
<Component {...rest} ChildRoutes={ChildRoutesWrapper}/>
</ChildRouteContext.Provider>
</Route>
);
})}
</Switch>
);
};
【问题讨论】:
标签: reactjs react-router react-router-dom