React Query useMutation задает mutationKey динамически

В моем проекте React с использованием React Query у меня есть функциональный компонент MoveKeywordModal, такой что:

  1. при первой загрузке он выбирает из конечной точки API api/keyword_lists, чтобы получить кучу keywordLists данных. Для каждого из этих keywordLists, назовите его list, я создаю интерактивный элемент.

  2. Когда щелкают по интерактивному элементу (заключенному в HoverWrapper), я хочу отправить запрос POST API на api/keyword_lists/:list_id/keyword_list_items/import с некоторыми данными. где :list_id - это идентификатор списка, по которому только что щелкнули.

export const MoveKeywordModal = ({
  setShowMoveKeywordModal,
  keywordsToMove
}) => {
  const { data: keywordLists } = useQuery('api/keyword_lists', {})
  const [newKeywordList, setNewKeywordList] = useState({})
  const { mutate: moveKeywordsToList } = useMutation(
    `api/keyword_lists/${newKeywordList.id}/keyword_list_items/import`,
    {
      onSuccess: data => {
        console.log(data)
      },
      onError: error => {
        console.log(error)
      }
    }
  )
  const availableKeywordLists = keywordLists
    .filter(l => l.id !== activeKeywordList.id)
    .map(list => (
      <HoverWrapper
        id={list.id}
        onClick={() => {
          setNewKeywordList(list)
          moveKeywordsToList({
            variables: { newKeywordList, data: keywordsToMove }
          })
        }}>
        <p>{list.name}</p>
      </HoverWrapper>
    ))

  return (
    <>
      <StyledModal
        isVisible
        handleBackdropClick={() => setShowMoveKeywordModal(false)}>
        <div>{availableKeywordLists}</div>
      </StyledModal>
    </>
  )
}

Несмотря на вызов setNewKeywordList(list) в onClick HoverWrapper, кажется, что newKeywordList.id все еще не определен, даже newKeywordList не определен.

Что мне делать, чтобы это исправить?

Спасибо!


person Johnson Liu    schedule 10.01.2021    source источник


Ответы (1)


response не выполняет обновления состояния немедленно, когда вы вызываете установщик useState - обновление просто "запланировано". Таким образом, даже если вы вызываете setNewKeywordList, у newKeywordList не будет нового значения в следующей строке кода - только в следующем цикле рендеринга.

Итак, пока вы находитесь в обработчике событий, вам нужно будет использовать переменную list:

setNewKeywordList(list)
moveKeywordsToList({
    variables: { newKeywordList: list, data: keywordsToMove }
 })

/ edit: Я только что понял, что ваш вызов useMutation неверен. У него нет key как useQuery, он должен предоставить функцию в качестве первого аргумента, который принимает переменные, известную как функция мутации:

  const { mutate: moveKeywordsToList } = useMutation(
    (variables) => axios.post(`api/keyword_lists/${variables.newKeywordList.id}/keyword_list_items/import`),
    {
      onSuccess: data => {
        console.log(data)
      },
      onError: error => {
        console.log(error)
      }
    }
  )

см. также: https://react-query.tanstack.com/guides/mutations

person TkDodo    schedule 10.01.2021
comment
Спасибо, я попробовал, он все еще вызывает API-вызов api/keyword_lists/undefined/keyword_list_items/import, а не получает атрибут id переменной newKeywordList и использует его. - person Johnson Liu; 10.01.2021
comment
Я изменил свой ответ - я пропустил, что вызов useMutation был неправильным - person TkDodo; 10.01.2021
comment
Спасибо, мы точно к цели! Выполнив `` const {mutate: moveKeywordsToList} = useMutation (variables = ›api/keyword_lists/${variables.newKeywordList.id}/keyword_list_items/import, {onSuccess: data =› {console.log ('on success') console.log (data)}, onError: error = ›{console .log (error)}}) `` Я создаю правильный URL, например api/keyword_lists/1/keyword_list_items/import Однако вызов API никогда не производился, и, похоже, он вызывает onSuccess обработчик напрямую и URL-адрес, указанный выше. - person Johnson Liu; 10.01.2021
comment
Да, функция мутации должна действительно выполнять публикацию или размещение запроса, например через axios.post. Пожалуйста, посмотрите связанные примеры - person TkDodo; 10.01.2021