React createContext/useContext 在页面之间不存在 [英] React createContext/useContext does not survive between pages
问题描述
我正在尝试为应用程序需要的所有组件创建一个共享的全局状态,而不是依赖于 props 钻取或 redux,我正在尝试使用 React Context 来实现这一点.
当我在路由之间切换时,为什么我的用户上下文不存在?下面的应用说明了这个问题.
我是否需要将任何其他钩子与 useContext
结合使用?
//index.js从反应"导入反应;从 'react-dom' 导入 ReactDOM;导入'./index.css';从'./App'导入应用程序;从./AuthenticationProvider"导入 { AuthenticationProvider };const 索引 = () =>{返回 (<认证提供者><应用程序/></AuthenticationProvider>);}ReactDOM.render( , document.getElementById('root'));
//App.jsimport React, { useState, useContext } from 'react';import { BrowserRouter as Router, Route, Switch } from "react-router-dom";导入'./App.css';从 './AuthenticationProvider' 导入 { AuthenticationContext };函数添加用户(){const [formUser, setFormUser] = useState("");const [user, setUser] = useContext(AuthenticationContext);const handleSubmit = 异步(事件)=>{event.preventDefault();设置用户(表单用户);}返回 (<React.Fragment>表单用户:{formUser}.<form id="form1" onSubmit={handleSubmit}><input type="text" id="user" onChange={event =>setFormUser(event.target.value)}/><input type="submit" value="保存"/></表单><br/>当前用户:{user}<br/><a href="/">返回首页</a></React.Fragment>);}函数主页(){const [user, setUser] = useContext(AuthenticationContext);返回 (<React.Fragment><div className="应用程序">你好{用户}.<br/><a href="/add">添加用户</a>
</React.Fragment>);}功能应用(){返回 (<路由器><开关><路由精确路径="/" component={Home}/><路由精确路径="/add" component={AddUser}/></开关></路由器>);}导出默认应用程序;
//AuthenticationProvider.jsimport React, { useState, createContext } from "react";const DEFAULT_STATE = "";出口 const AuthenticationContext = createContext(DEFAULT_STATE);导出 const AuthenticationProvider = ({ children }) =>{const [user, setUser] = useState(DEFAULT_STATE);返回 (<AuthenticationContext.Provider value={[user, setUser]} >{孩子们}</AuthenticationContext.Provider>);}
问题是您使用常规 链接浏览应用程序,并且每次从
Home
到 addUser
应用程序刷新.要在不刷新页面的情况下浏览应用程序,请使用 Link
来自 react-router-dom
在 Home
和 AddUser
中将 a
链接更改为 Link
组件
import { Link } from "react-router-dom";函数主页(){const { user, setUser } = useContext(AuthenticationContext);返回 (<React.Fragment><div className="应用程序">你好{用户}.<br/><Link to="/add">添加用户</Link><-- 将 a 改为链接
</React.Fragment>);}函数添加用户(){const [formUser, setFormUser] = useState("");const [user, setUser] = useContext(AuthenticationContext);const handleSubmit = 异步(事件)=>{event.preventDefault();设置用户(表单用户);}返回 (<React.Fragment>表单用户:{formUser}.<form id="form1" onSubmit={handleSubmit}><input type="text" id="user" onChange={event =>setFormUser(event.target.value)}/><input type="submit" value="保存"/></表单><br/>当前用户:{user}<br/><Link to="/">返回首页</Link><-- 将 a 改为链接</React.Fragment>);}
I am trying to create a shared global state for all components that an app needs, and instead of relying on props drilling or redux, I am trying to achieve that with the React Context.
Why does my user context not survive when I switch between routes? The application bellow illustrates the issue.
Do I need to use any other hook in conjunction with useContext
?
//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { AuthenticationProvider } from "./AuthenticationProvider";
const Index = () => {
return (
<AuthenticationProvider>
<App />
</AuthenticationProvider>
);
}
ReactDOM.render(<Index />, document.getElementById('root'));
//App.js
import React, { useState, useContext } from 'react';
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import './App.css';
import { AuthenticationContext } from './AuthenticationProvider';
function AddUser() {
const [formUser, setFormUser] = useState("");
const [user, setUser] = useContext(AuthenticationContext);
const handleSubmit = async (event) => {
event.preventDefault();
setUser(formUser);
}
return (
<React.Fragment>
Form user: {formUser}.
<form id="form1" onSubmit={handleSubmit}>
<input type="text" id="user" onChange={event => setFormUser(event.target.value)} />
<input type="submit" value="Save" />
</form>
<br/>
Current user: {user}
<br/>
<a href="/">Back to home</a>
</React.Fragment>
);
}
function Home() {
const [user, setUser] = useContext(AuthenticationContext);
return (
<React.Fragment>
<div className="App">
Hello {user}.
<br/>
<a href="/add">Add user</a>
</div>
</React.Fragment>
);
}
function App() {
return (
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/add" component={AddUser} />
</Switch>
</Router>
);
}
export default App;
//AuthenticationProvider.js
import React, { useState, createContext } from "react";
const DEFAULT_STATE = "";
export const AuthenticationContext = createContext(DEFAULT_STATE);
export const AuthenticationProvider = ({ children }) => {
const [user, setUser] = useState(DEFAULT_STATE);
return (
<AuthenticationContext.Provider value={[user, setUser]} >
{children}
</AuthenticationContext.Provider>
);
}
The problem is that you used a regular <a>
link to navigate through the app and every time you go from Home
to addUser
the app refreshes. To navigate through the app without refreshing the page use the Link
component from react-router-dom
in Home
and AddUser
change the a
links to the Link
component
import { Link } from "react-router-dom";
function Home() {
const { user, setUser } = useContext(AuthenticationContext);
return (
<React.Fragment>
<div className="App">
Hello {user}.
<br />
<Link to="/add">Add user</Link> <-- Changed a to Link
</div>
</React.Fragment>
);
}
function AddUser() {
const [formUser, setFormUser] = useState("");
const [user, setUser] = useContext(AuthenticationContext);
const handleSubmit = async (event) => {
event.preventDefault();
setUser(formUser);
}
return (
<React.Fragment>
Form user: {formUser}.
<form id="form1" onSubmit={handleSubmit}>
<input type="text" id="user" onChange={event => setFormUser(event.target.value)} />
<input type="submit" value="Save" />
</form>
<br />
Current user: {user}
<br />
<Link to="/">Back to home</Link> <-- Changed a to Link
</React.Fragment>
);
}
这篇关于React createContext/useContext 在页面之间不存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!