Реакция createContext / useContext не сохраняется между страницами - PullRequest
1 голос
/ 15 июня 2019

Я пытаюсь создать общее глобальное состояние для всех компонентов, в которых нуждается приложение, и вместо того, чтобы полагаться на детализацию или редукцию, я пытаюсь достичь этого с помощью контекста React.

Почему мой пользовательский контекст не сохраняется, когда я переключаюсь между маршрутами? Приложение ниже иллюстрирует проблему.

Нужно ли использовать какой-либо другой крючок в сочетании с 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>
  );
}

1 Ответ

2 голосов
/ 15 июня 2019

Проблема в том, что вы использовали обычную ссылку <a> для навигации по приложению, и каждый раз, когда вы переходите от Home к addUser, приложение обновляется. Для навигации по приложению без обновления страницы используйте компонент Link из react-router-dom

in Home и AddUser изменяют ссылки a на компонент Link

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>
  );
}
...