#javascript #reactjs #routes #state
#javascript #reactjs #маршруты #состояние
Вопрос:
Я новичок в React и использую Zustand для работы с глобальными магазинами. Моя цель в данном конкретном случае — перенаправить на страницу «RSVP», если найден правильный пользователь.
Сценарий A: Пользователь найден в базе данных. Переход на новую страницу
Сценарий B: пользователь не найден в базе данных. Оставайтесь на текущей странице и выводите сообщение об ошибке
Это кажется простым, если вы хотите добиться этого по щелчку мыши, однако я не могу найти никакой информации о том, как запустить его в состоянии.
Я понимаю, что useHistory можно использовать, но только внутри функции, поэтому она не работает, когда я пытаюсь использовать ее в состоянии. например.
import create from 'zustand';
import { mountStoreDevtool } from 'simple-zustand-devtools';
import { useHistory } from "react-router-dom";
const useStore = create((set, get) => ({
guests: [],
currentGuests: [],
message: "Please enter your unique password found in your email.",
returnDatabase: (input) => {
const guests = get().guests;
const targetParty = guests.filter((guest) => guest.party === input);
if (targetParty.length !== 0) {
set({ currentGuests: targetParty });
const setMessage = "Please enter your unique password found in your email.";
set({ message: setMessage });
//I want to programatically redirect here
let history = useHistory();
history.push("/rsvp");
} else {
const setMessage = "Your password has not been found. Please check your email and try again.";
set({ message: setMessage });
}
},
setStore: (data) => {
const guestsData = data.guests;
set({ guests: guestsData });
},
}));
Однако я получаю эту ошибку:
Failed to compile
src/store/storeUtil.js
Line 19:21: React Hook "useHistory" is called in function "returnDatabase" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter react-hooks/rules-of-hooks
Search for the keywords to learn more about each error.
Я полагаю, это потому, что его нет в функции, поэтому я попытался поместить его в отдельный компонент:
import create from 'zustand';
import { mountStoreDevtool } from 'simple-zustand-devtools';
import { useHistory } from "react-router-dom";
export function RsvpButton(){
let history = useHistory();
function handleClick() {
history.push("/rsvp");
}
return (
{handleClick}
);
}
const useStore = create((set, get) => ({
guests: [],
currentGuests: [],
message: "Please enter your unique password found in your email.",
returnDatabase: (input) => {
const guests = get().guests;
const targetParty = guests.filter((guest) => guest.party === input);
if (targetParty.length !== 0) {
set({ currentGuests: targetParty });
const setMessage = "Please enter your unique password found in your email.";
set({ message: setMessage });
//try to use component here
<RsvpButton />
...etc
И это просто ничего не делает / не имеет ошибок. Должен ли я использовать другой метод для маршрутизации на страницу RSVP, отличную от useHistory? Или я делаю что-то не так в своей реализации?
Ответ №1:
Ваш компонент кнопки rsvp but не создает кнопку.
Код для функции RSVP Button должен быть примерно таким
export function RsvpButton () {
...
return (
<button onClick={handleClick}>Rsvp</button>
)
}
Таким образом, handleClick
функция будет связана со onClick
свойством кнопки, что заставит ее запускаться при нажатии кнопки.
Комментарии:
1. Привет, Ритурадж, спасибо за ответ. Моя проблема в том, что я хочу, чтобы он запускался вручную (т. Е. Не По щелчку) в зависимости от логики. Если пользователь находится в списке: инициируйте маршрут, если пользователя нет в списке: оставайтесь на той же странице и выводите сообщение об ошибке, я отредактирую вопрос для большей ясности.
Ответ №2:
Решение для всех, у кого есть подобная проблема:
Чтобы решить эту проблему, я поместил обработчик useHistory в родительский компонент RsvpContainer.js
import { useHistory } from 'react-router-dom';
useEffect(() => {
loadData();
});
return (
<React.Fragment>
<div className="header">
<div className="Bg section-2"></div>
<div className="divider"></div>
<div className="App section-2">
<h3>RSVP.</h3>
<h2>Saturday 30 October, 2021</h2>
<Input
filter={filter}
setFilter={setFilter}
returnDatabaseHandler={returnDatabaseHandler}
onUserFound={onUserFoundHandler}
/>
</div>
</div>
</React.Fragment>
)
Input.js
export function Input({ setFilter, filter, onUserFound }) {
const isUserFound = useStore((state) => state.isUserFound);
useEffect(() => {
if (isUserFound) {
onUserFound();
}
}, [isUserFound]);
}
storeUtil.js (zustand global store) — я добавил это в ‘returnDatabase’
set({
message: setMessage,
isUserFound: true
});