Потеря данных компонента на странице refre sh в React - PullRequest
1 голос
/ 20 июня 2020

Я работаю над тем, где мне нужно поддерживать состояние уровня приложения, то есть глобальное состояние, я использую для этого useContext и useReducer.

Так что я делаю на кнопке щелкните Я настраиваю свой контекст, а затем использую его, как мое приложение, зарегистрировав поставщика в моем App.js.

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

Но это не должно быть так, я хочу сделать свои данные глобальными и при refre sh они не должны теряться

Мой код

Мой файл контекста

import React, { useReducer, createContext } from "react";

const initialstate = {
  someData: null
};

const MyContext = createContext({
  someData: null,
  click_btn: d => {}
});
const MyReducer = (state, action) => {
  switch (action.type) {
    case "BTNCLICKED":
      return {
        ...state,
        someData: action.payload
      };

    default:
      return state;
  }
};

const MyProvider = props => {
  const [state, dispatch] = useReducer(MyReducer, initialstate);
  const click_btn = d => {
    dispatch({
      type: "BTNCLICKED",
      payload: d
    });
  };

  return (
    <MyContext.Provider
      value={{ someData: state.someData, click_btn }}
      {...props}
    />
  );
};

export { MyContext, MyProvider };

Мой домашний код, в котором я устанавливаю контекст

    import React, { useContext, useState } from "react";
import history from "../History/history";

import { MyContext } from "../context/testContext";

function Test() {
  const context = useContext(MyContext);
  const [data, setdata] = useState(null);
  const clickEvt = () => {
    setdata("Setting data");
    context.click_btn(data);
  };
  return (
    <div>
      <input type="button" onClick={clickEvt} value="Click Me" />
    </div>
  );
}

export default Test;

И мое приложение. js файл

    import React from "react";
import "./styles.css";
import { MyProvider } from "./context/testContext";
import { Router } from "react-router-dom";
import history from "./History/history";
import Routes from "./myRoutes";

export default () => {
  return (
    <MyProvider>
      <Router history={history}>
        <div className="App wrapper">
          <Routes />
        </div>
      </Router>
    </MyProvider>
  );
};

Пожалуйста, проверьте рабочий код Мои коды и ссылка на ящик

Пожалуйста, проверьте инструменты разработчика React

On click my developer tool image

Когда я обновляю sh инструмент разработчика страниц

Ответы [ 3 ]

0 голосов
/ 20 июня 2020

Чтобы сохранить контекст React, или хранилище redux, или что-то еще, что находится в памяти вашего приложения, вам нужно сохранить его снаружи, а затем перезагрузить его при запуске приложения (когда вы нажимаете F5, страница обновляется, ваше приложение React перезапускается, поэтому он теряет все состояния компонентов, контексты, хранилища ...).

Например, вы можете сохранить свой контекст в локальном хранилище и изменить свой контекст, чтобы он начинался с поиска сохраненного значения и перезагружал его первый. Это можно сделать с помощью useEffect в вашем контексте: каждый раз, когда он изменяется, сохраняйте его в локальном хранилище и предварительно загружайте значение локального хранилища при запуске:

// context
[...]

useEffect(() => {
  if(localStorage.getItem('myKey')) {
    setState(localStorage.getItem('myKey');
  }
}, []);

useEffect(() => {
  localStorage.setItem('myKey', state);
}, [state]);

Примерно так это можно сделать, он может использовать рефакторинг.

Вы также можете сохранить свой контекст на удаленном сервере или в локальной SQL DB. У вас будет множество решений:

0 голосов
/ 20 июня 2020

Из вашего комментария

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

В этом случае LocalStorage является клиентской стороной, а response - фреймворком, который также является клиентской стороной. Все что угодно на стороне клиента можно редактировать любым способом. Вы не можете полагаться на данные на стороне клиента, предполагая злонамеренный умысел. Если есть что-то, что React может получить или отредактировать, это может отредактировать любой, у кого есть JS знания.

Единственное, чему вы можете доверять, так это своему внутреннему серверу. Клиент отправляет то, что пользователь хочет сделать, и сервер проверяет его, затем обрабатывает запрос, отправляет результат клиенту.

Вы можете выполнить поиск по этому ключевому слову для получения более подробной информации.

client server prevent cheat

0 голосов
/ 20 июня 2020

Отсутствует механизм сохранения. Вы можете расширить функцию MyProvider, чтобы она получала значение из localStorage или api

Пример для API


const MyProvider = props => {
  const [state, dispatch] = useReducer(MyReducer, initialstate);
  const click_btn = payload => {
    saveStateToApi(payload)
      .then(result => {
         dispatch({
           type: "BTNCLICKED",
           payload
         });
      })
  };

  useEffect(() => {
    getLastStateFromApi()
      .then(data => {
        dispatch({
          type: "BTNCLICKED",
          payload: data
        });
      })

  }, [])

  return (
    <MyContext.Provider
      value={{ someData: state.someData, click_btn }}
      {...props}
    />
  );
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...