У меня есть форма, в которой есть поле с именем description
, где при нажатии кнопки с именем query
выполняется запрос POST
, а затем отправляется текст в поле description
в теле запроса.
Я использую для этого useReducer и не знаю, как структурировать действие и useEffect, когда пользователь нажимает кнопку query
.
Action for querying the data(I am not sure what to return in this case)
switch (action.type) {
case "query": {
return {
...state,
};
}
}
Making the POST request and setting the JSON data in state which is then displayed(Takes as input the data from the field description)
const fetchData = async (desc) => {
const response = await fetch("/rank", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ terms: desc }),
}).catch((e) => console.info(e));
const dataJSON = await response.json().catch((e) => console.info(e));
if (response.ok) {
console.info("OK");
}
if (!response.ok) {
const error = (dataJSON && dataJSON.message) || response.status;
return Promise.reject(error);
}
setData(dataJSON.data);
};
useEffect(() => {
fetchData(description);
}, [description]);
Button for making the query
<Button
type = "button"
onClick = {() => {
dispatch({ type: "query" });
}}
>
Все это работает, но проблема в том, что хук useEffect
срабатывает, даже когда я не нажимаю кнопку для запроса, поскольку я не знаю, как настроить для него действие.
🤔 А знаете ли вы, что...
JavaScript - это скриптовый язык программирования, разработанный Netscape Communications Corporation.
Не вижу смысла использоватьEffect для fetchData. вы хотите, чтобы эта функция вызывалась только при отправке, а не при каждом обновлении состояния.
также у вас есть своего рода setData
. это приведет к дублированию состояния после использования useReducer. Я бы посоветовал удалить эти данные state
, если вы используете здесь редуктор.
Я бы рекомендовал действие onClick вызывать fetchData и отправлять действие в случае успеха.
const fetchData = async () => {
try {
const response = await fetch("/rank", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ terms: description }),
})
const dataJSON = await response.json();
if (response.ok) {
console.info("OK");
}
if (!response.ok) {
const error = (dataJSON && dataJSON.message) || response.status;
throw error;
}
dispatch({ type: "query", data: dataJSON.data });
} catch (error) {
console.info(error)
}
};
тогда ваш редуктор на вашем редукторе:
switch (action.type) {
case "query":
return {...state, action.data };
default:
return state;
}
вы также можете добавить некоторые дополнительные действия отправки, такие как loading
, success
и error
, чтобы обрабатывать эти случаи, если это необходимо.