#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)