React createContext/useContext 在页面之间不存在 [英] React createContext/useContext does not survive between pages

查看:48
本文介绍了React createContext/useContext 在页面之间不存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为应用程序需要的所有组件创建一个共享的全局状态,而不是依赖于 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>);}

解决方案

问题是您使用常规 链接浏览应用程序,并且每次从 HomeaddUser 应用程序刷新.要在不刷新页面的情况下浏览应用程序,请使用 Link 来自 react-router-dom

的组件

HomeAddUser 中将 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屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆