Состояние реакции теряется, когда пользователь обновляет страницу

#javascript #reactjs

Вопрос:

Я новичок в React/Node и работаю над учебным проектом. Это платформа, которая соединяет пользователей (фрилансеров) с некоммерческими компаниями. Когда пользователь входит в систему, он может просмотреть список компаний и нажать кнопку, чтобы подключиться к этой компании. Затем они могут перейти на страницу Подключения пользователей, чтобы просмотреть все компании, с которыми они были связаны.

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

Я, вероятно, неправильно использую состояние. Я отслеживаю два разных состояния. Первый — это когда пользователь только что установил «свежее» соединение. Во-вторых, когда они посещают свою страницу подключения пользователей, я извлекаю их «старые» подключения из базы данных.

Что я могу сделать, чтобы убедиться, что состояние соединения сохраняется, если пользователь обновит страницу или вернется позже? Мой код приведен ниже (сокращен, чтобы включать только соответствующий код)

App.js

 function App() {

  const [currentUser, setCurrentUser] = useState(null);
  const [connectionHandles, setConnectionHandles] = useState([]);

//   Check if connected to this company 
  function hasConnectedToCompany(companyHandle) {
    return connectionHandles.includes(companyHandle);
  }

//   Make the connection in the database
  function connectToCompany(companyHandle) {
    if (hasConnectedToCompany(companyHandle)) return;
    VolunteerApi.connectToCompany(currentUser.username, companyHandle);
    setConnectionHandles([...connectionHandles, companyHandle]);
  }

  return (
    <BrowserRouter>
      <UserContext.Provider value={{ connectionHandles, setConnectionHandles, currentUser, setCurrentUser, hasConnectedToCompany, connectToCompany }}>
        <div>
          <Navigation />
          <Routes />
        </div>
      </UserContext.Provider>
    </BrowserRouter>
  );
}
 

CompanyDetail.js

 function CompanyDetail() {
  const { companyHandle } = useParams();
  const [company, setCompany] = useState(null);

  const { currentUser, hasConnectedToCompany, connectToCompany } = useContext(UserContext);
  const [connected, setConnected] = useState();

  React.useEffect(function updateConnectedStatus() {
    setConnected(hasConnectedToCompany(companyHandle));
  }, [companyHandle, hasConnectedToCompany]);
  

//   Handle connect 
  async function handleConnect(evt) {
    if (hasConnectedToCompany(companyHandle)) return;
    connectToCompany(companyHandle);
    setConnected(true);

    let connectUserInDb;
    try {
      connectUserInDb = await VolunteerApi.connectToCompany(currentUser.username, companyHandle);
    } catch (err) {
      setFormErrors(err);
      return;
    }
  }

  if (currentUser) {
    return (
      <div>         
            <h1>{company.companyName}</h1>            
            <p>
              <button onClick={handleConnect} disabled={connected}> {connected ? "Connected" : "Connect"} </button>              
            </p>
      </div>
    );
  } 
}
 

UserConnections.js

 function UserConnections() {
  const { currentUser, connectionHandles } = useContext(UserContext);
  const [companies, setCompanies] = useState([]);

  useEffect(() => {
    let isMounted = true;
    const connections = currentUser.connections.concat(connectionHandles);
    const comps = connections.map((c) => VolunteerApi.getCurrentCompany(c));
    Promise.all(comps).then(comps => isMounted amp;amp; setCompanies(comps));
    return () => { isMounted = false };
  }, [currentUser, connectionHandles]);

  if (!companies || companies.length === 0) {
    return (
      <div>
        <div>
          <p>You have no connections</p>
        </div>
      </div>
    )
  } else {
    return (
      <div>
        <div>
          <h1>Connections</h1>
          {companies amp;amp; companies.map(c => (
            <CompanyCard
              key={c.companyHandle}
              companyHandle={c.companyHandle}
              companyName={c.companyName}
            />
          ))}
        </div>
      </div>
    );
  }
};
 

Комментарии:

1. Правильно, состояние не сохраняется. Однако ваша база данных работает, поэтому все, что вам нужно сделать, это загрузить состояние из базы данных при подключении вашего приложения. Не уверен, что вы подразумеваете под «старым» состоянием, каждое изменение состояния должно немедленно сохраняться в базе данных, иначе вы потеряете его при обновлении. Если у вас есть две страницы/компонента, которые должны отображать состояние БД, вам необходимо загрузить состояние БД в обоих компонентах или в общем родительском элементе.


Ответ №1:

состояние будет сброшено при обновлении страницы, но вы можете либо использовать базу данных для сохранения соединения, либо использовать локальное хранилище.

Ответ №2:

Действительно, состояние теряется с помощью React при обновлении страницы.

Вы должны использовать другой метод, чтобы сохранить эту информацию, даже если пользователь обновит страницу. Вот варианты:

  • В базе данных. Может сработать, если пользователь находится за аутентификацией (паролем для входа). Пример пользователя name: Paul , id; 3131 , действительно нажал на кнопку «подключиться». В вашей базе данных вы добавляете столбец в таблицу User под названием userConnect = true
  • В URL-адресе. Как только пользователь нажмет на кнопку «подключиться», вы измените URL React router -адрес . Например , URL-адрес был mydomain.com , и после нажатия он становится mydomain.com?clicked=true . Если пользователь обновит вашу страницу, у вас все равно останется информация о пользователе, который нажал на кнопку.
  • В файле cookie (Более подробная информация здесь https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies)
  • В локальном хранилище (Более подробная информация здесь https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/local)