react-query: повторная выборка запроса только при изменении переменной состояния

#javascript #reactjs #caching #state-management #react-query

#javascript #reactjs #кэширование #управление состоянием #react-query

Вопрос:

У меня есть меню выбора параметров. Итак, когда пользователь выбирает опцию, я хочу отправить GET / request на сервер с этой опцией и получить отфильтрованные данные с сервера.

Это может быть достигнуто с помощью useEffect(() => {// отправить запрос}, [критерии])

Потому что useEffect гарантирует, что запрос будет отправлен на сервер только в том случае, если setCriteria завершен.

Но я использую react-query библиотеку. таким образом, его нельзя использовать useQuery внутри useEffect .

В результате запрос отправляется на сервер до завершения setState. Таким образом, сервер получает предыдущее выбранное значение, а не текущее выбранное значение.

onChange:

 <select
  name="filter"
  value={criteria}
  onChange={async (e) => {
    setCriteria(e.target.value);
  }}
>
  <option>Most recent First</option>
  <option>Price: Low to High</option>
  <option>Price: High to Low</option>
</select>;
  

Выборка сообщений:

  const FetchPosts = async () => {
    const {
      data: { posts },
    } = await axios.get(`${process.env.API_URL}/api/posts`, {
      params: {
        filter: criteria,
      },
    });

    return posts;
  };

 useQuery("posts", FetchPosts);

 const posts = queryCache.getQueryData("posts");
  

Ответ №1:

Вы можете использовать свои критерии в качестве ключа запроса. Всякий раз, когда изменяется ключ запроса, запрос автоматически обновляется.

 const FetchPosts = async ({criteria}) => {
    console.log(criteria) //from useQuery key

    //your get api call here with criteria params

    return posts;
};

const [criteria, setCriteria] = useState("")

const {isLoading, data: post} = useQuery(["posts", criteria], FetchPosts); //include criteria state to query key

console.log(post) 

<select
  name="filter"
  value={criteria}
  onChange={(e) => {
    setCriteria(e.target.value);  // trigger a re-render and cause the useQuery to run the query with the newly selected criteria
  }}
>
  <option>Most recent First</option>
  <option>Price: Low to High</option>
  <option>Price: High to Low</option>
</select>
  

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

1. У меня другой вариант использования. Как мне НЕ запускать useQuery при каждом изменении критерия? Я хочу выполнять выборку только во время первоначального рендеринга и при запуске действия (например: нажатие кнопки Применить фильтр)

2. @TA3 У меня такие же сомнения, какие-либо решения?

3. @TA3 и @asds_asds Если вы не задаете свой параметр как часть ключа запроса, ваш запрос не будет выполняться при изменении критерия. Например: useQuery("thisIsAStaticKey", doSomething());

4. Спасибо, чувак! Могу ли я также сделать это для нескольких массивов?

Ответ №2:

На вопрос уже дан ответ. Вот мои два цента:

Обрабатывайте ключи запроса useQuery как массив зависимостей useEffect . Всякий раз, когда выполняется запрос key changes.

Если вы все еще хотите управлять запуском запросов, вы можете использовать опцию «включено» для перехвата useQuery.

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

1. Привет, можем ли мы отправить тело json в get-запросе useQuery?