Как перенаправить после получения запроса

1656553928 kak perenapravit posle polucheniya zaprosa

от Джун Хюк Кима

1nGG9CsCAEXi4Q5uwCPOPOMzF-pcOUv9ifpp

GraphQL является горячим, и для этого есть уважительная причина. Короче говоря, это язык запросов, позволяющий спрашивать точно что вам нужно от вашего API. Это уменьшает ненужную передачу данных, которая может происходить с помощью различных методологий.

Я работал над проектом, где использовался сервер GraphQL. Я решил использовать React и Apollo Client в качестве моего интерфейса для связи с моим сервером GraphQL. У меня возникли определенные трудности, чтобы понять, как повторно получить запрос, а затем перенаправить мою страницу на главную страницу с обновленными данными. Вот где все стало немного труднее.

Для меня проблема заключалась в том, чтобы выяснить, как на самом деле называлась мутация и что было возвращено. Мы можем получить доступ к мутации после подключения через graphql(mutation)(*YourComponent*) через this.props.mutate(). Эта функция возвращает Promise. Мы можем цепочкой .then() функции вызова функций после мутации. Функция mutate также может принимать переменные для мутации. Полный пример будет примерно таким:

this.props.mutate({  variables:{    title: this.state.title,    content: this.state.content  }})

Это означало бы, что наша мутация принимает две переменные, которые называются заглавием и содержимым. Они передаются в нашу мутацию, когда мы посылаем ее на наш внутренний сервер. Скажем, наша мутация – это добавление примечания с названием и содержимым. Чтобы все было понятно, я приведу простой пример того, как будет выглядеть наша мутация:

const mutation = gql`  mutation AddNote($title: String, $content: String){    addNote(title:$title, content:$content){      title      content    }  }}`
// Our component should also be connected to Apollo client, so // something like this
export default graphql(mutation)(Component)

Итак, что происходит после выполнения этой функции? Наш бэк-энд получает информацию и происходит мутация. Однако наш интерфейс не знает, что произошла мутация. Он не возвращает запрос, который мы получили ранее (в нашем случае, возможно, что-то вроде fetchAllNotes). Вот где функция мутации становится очень удобной. Мы можем передать переменную с названием refetchQueriesс помощью которого будут получены любые запросы, которые мы просим.

this.props.mutate({  variables:{    title: this.state.title,    content: this.state.content  },  refetchQueries:[{    query: fetchAllNotes  }]}).then(() => this.props.history.push('/notes'))

В этом случае мы сообщаем клиенту Apollo повторно получить fetchAllNotesquery после возникновения мутации. Затем перенаправить пользователя на /notes каталог (React-Router). Помните, что наша функция mutate возвращает Promise? Все это должно работать, не правда ли? Ну… по задумке, команда Apollo так и сделала refetchQueries случилось бы в это же время как .then заявление. Это означает, что оператор .then может встречаться раньше refetchQueries. Это может привести к тому, что компонент, которому требуется обновленная информация, не будет обновляться.

В этом конкретном случае наш пользователь будет перенаправлен раньше в refetchQueries происходит. Информация не будет обновляться. Это сложно, поскольку функция mutate возвращает Promise. Команда Apollo прошла мимо дизайн так что refetchQueries может происходить рядом с любым .then заявления. Итак, как мы справимся с этим?

Команда Apollo поняла, что это может быть проблемой. Они пришли с решением, которое разрешает refetchQueries принять переменную, которая позволит ей вернуть Promise, и, таким образом, произойдет перед любым .then заявления. Наш код будет выглядеть примерно так:

this.props.mutate({  variables:{    title: this.state.title,    content: this.state.content  },  refetchQueries:[{    query: fetchAllNotes,    variables:{      awaitRefetchQueries: true    }  }]}).then(() => this.props.history.push('/notes'))

Если это сработало для вас, уууу! Похоже, исправление сработало! Однако лично для меня это не сработало. Кроме того, поскольку он доступен только в последних версиях Apollo Client, он не будет доступен в старых версиях Apollo Client.

Мне пришлось немного решить проблемы с жизненными циклами компонентов React, чтобы убедиться, что мой компонент будет правильно отображать обновленные данные. Именно исправление достаточно короткое и достаточно простое! На компоненте My Notes, который воспроизводит заметки и подключается к fetchAllNotes запрос на graphql функцию, я добавил быстрое исправление, чтобы убедиться, что мои данные правильно отображаются.

componentDidUpdate(prevProps){  if(prevProps.data.notes && prevProps.data.notes.length !==     this.props.data.notes.length){    // Logic to update component with new data  }}

По сути мы говорим, что когда компонент обновляется, мы хотим увидеть, был ли запрос на заметки ранее завершен (проверяя, prevProps.data.notes существует) и если длина данных поменялась. Это позволяет нашему компоненту React обновлять информацию после завершения запроса на повторную выборку.

Теперь все должно работать! Надеюсь, awaitRefetchQueries переменная сработала для вас и становится более известной, что является гораздо более элегантным решением. Однако найти примеры/документацию по использованию довольно трудно awaitRefetchQueries правильно. Пока достаточно хорошего понимания жизненных циклов компонентов React, чтобы помочь вам обойти «помехи» Apollo + React!

Пожалуйста, оставляйте любые отзывы или вопросы в комментариях и я сделаю все возможное, чтобы помочь. Я ни в коем случае не эксперт, но я бы хотел вместе с вами решить проблему и помочь разобраться!

Добавить комментарий

Ваш адрес email не будет опубликован.