英文:
How to Lift State Up w/ React Router 6?
问题
我在思考如何在我的两个路由之间共享状态。我应该将状态从我的AddContact
组件提升到Layout
或App
以便分享给ContactList
。我的Layout
组件只渲染一个Header
和Outlet
组件。
英文:
I am wondering how to share state between my two routes. Should I lift state up from my AddContact
component to Layout
or App
to share to ContactList
. My Layout
component is just rendering a Header
and Outlet
component.
function App() {
const [contacts, setContacts] = useState([])
return (
<BrowserRouter>
<Routes>
<Route element={<Layout />}>
<Route path='/' element={<ContactList />} />
<Route path='/add' element={<AddContact />} />
</Route>
</Routes>
</BrowserRouter>
);
}
答案1
得分: 3
你可以将状态提升到 App
,然后将需要的内容作为 props 传递给每个路由组件。
示例:
function App() {
const [contacts, setContacts] = useState([]);
return (
<BrowserRouter>
<Routes>
<Route element={<Layout />}>
<Route
path="/"
element={<ContactList contacts={contacts} />}
/>
<Route
path="/add"
element={<AddContact setContacts={setContacts} />}
/>
</Route>
</Routes>
</BrowserRouter>
);
}
另一种方法是将状态存储在 Layout
布局路由组件中,并通过 Outlet
组件的上下文来提供。路由组件可以通过 useOutletContext
钩子访问提供的上下文值。
function App() {
return (
<BrowserRouter>
<Routes>
<Route element={<Layout />}>
<Route path="/" element={<ContactList />} />
<Route path="/add" element={<AddContact />} />
</Route>
</Routes>
</BrowserRouter>
);
}
const Layout = () => {
const [contacts, setContacts] = useState([]);
return (
...
<Outlet context={{ contacts, setContacts }} />
...
);
};
const ContactList = () => {
const { contacts } = useOutletContext();
...
};
const AddContact = () => {
const { setContacts } = useOutletContext();
...
};
这主要取决于个人喜好或范围,例如,子 React 树中需要多少部分访问状态。
英文:
You could lift it to either.
If lifting state to App
you can pass what you need down as props to each routed component.
Example:
function App() {
const [contacts, setContacts] = useState([]);
return (
<BrowserRouter>
<Routes>
<Route element={<Layout />}>
<Route
path="/"
element={<ContactList contacts={contacts} />}
/>
<Route
path="/add"
element={<AddContact setContacts={setContacts} />}
/>
</Route>
</Routes>
</BrowserRouter>
);
}
The alternative is to locate the state in the Layout
layout route component and expose via the Outlet
component's context. The routed components would access the provided context value via the useOutletContext
hook.
function App() {
return (
<BrowserRouter>
<Routes>
<Route element={<Layout />}>
<Route path="/" element={<ContactList />} />
<Route path="/add" element={<AddContact />} />
</Route>
</Routes>
</BrowserRouter>
);
}
const Layout = () => {
const [contacts, setContacts] = useState([]);
return (
...
<Outlet context={{ contacts, setContacts }} />
...
);
};
const ContactList = () => {
const { contacts } = useOutletContext();
...
};
const AddContact = () => {
const { setContacts } = useOutletContext();
...
};
It basically comes down to preference, or scope in my opinion, e.g. how much of the sub-ReactTree needs to access the state.
答案2
得分: 1
以下是已翻译的内容:
这里有一个示例,使用状态而不是状态管理系统。
假设我们有两个兄弟组件:page1 和 page2。如果我们需要将数据从 page1 组件传递到 page2 组件,我们可以在 react-router-dom v6 中使用 hooks。
import { Link } from 'react-router-dom';
const Page1 = () => {
return (
<Link to='/page2' state={{ msg: "来自page1的问候" }}>前往 Page2</Link>
);
}
export default Page1;
在 page2 组件中,您可以像这样接收对象。
import { useLocation } from "react-router-dom";
const Page2 = (props) => {
const { state } = useLocation();
return <div>{state.msg}</div>
}
export default Page2;
英文:
Here is an example using states and not state management systems.
Let's assume that we've got 2 sibling components; page1 and page2. If we need to pass data from the page1 component to the page2 component, we can use hooks in react-router-dom v6.
import {Link} from 'react-router-dom';
const Page1 = () => {
return (
<Link to={'/page2'} state: {msg: "hello from page1"}>Go to Page2</Link>
);
}
export default Page1;
On the page2 component, you can receive the object like that.
import { useLocation } from "react-router-dom";
const Page2 = (props) => {
const { state } = useLocation();
return <div>{state.msg}</div>
}
export default Page2;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论