Как переслать данные на следующую страницу с помощью Apollo и NextJS - PullRequest
5 голосов
/ 29 марта 2020

Я работаю над веб-приложением с Next JS, Apollo и React (хуки).

У меня есть форма, которая запрашивает имя посетителя в качестве первого шага в процессе регистрации. При отправке формы имя будет сохранено в кеше Apollo, и посетитель будет перенаправлен на следующую страницу.

import React, { useState } from 'react';
import Router , {useRouter}  from 'next/router';
import { useApolloClient } from '@apollo/react-hooks';


const NameForm = props => {
    const [name, setName] = useState("");
    const client = useApolloClient();
    const router = useRouter();

    const handleSubmit = e => {
        e.preventDefault();

        if(!name) return;

        client.writeData({ data: { name } });
        router.push('/user/register');
    }

    return (
        <form onSubmit={handleSubmit}>
            <div>
                <label htmlFor="name">Naam</label>
                <div>
                    <input type="text" id="name" name="name" value={name} onChange={e => setName(e.target.value)} />
                    <button type="submit" onClick={handleSubmit}>Get started</button>
                </div>
            </div>
        </form>
    )
}

export default NameForm;

Следующая страница содержит более обширную форму. Когда посетители приходят с домашней страницы, имя уже известно, и я хочу вернуть его из кеша. Я думал, что

import { gql } from 'apollo-boost';
import { useApolloClient } from '@apollo/react-hooks';
import AddUserForm from '../../components/forms/AddUserForm';

const GET_NAME = gql` 
 query GetName {
    name @client  
}`;

const AddUser = ({ name }) => (
    <React.Fragment>
        <AddUserForm name={name} />
    </React.Fragment>
)

AddUser.getInitialProps = async ctx => {
    const client = useApolloClient();
    const name = await client.cache.readQuery({ query: GET_NAME });

    return { name: name || '' };
}

export default AddUser;

Я думал, что смогу сделать это в getInititialProps. Перехватчики разрешены только в теле функционального компонента.

Из-за непрерывного развития перехватчиков реагирования и apollo Я пропускаю учебник / курс по этому вопросу, и мне трудно найти правильный способ сделать это.

Я надеюсь, что кто-то здесь может помочь мне в дальнейшем.

1 Ответ

3 голосов
/ 03 апреля 2020

использование кеша apollo-client может привести к некоторым вопросам, которые действительно зависят от реализации apollo-client и nextjs. Если вы откроете свое приложение, введя URL-адрес в адресную строку браузера, Next.js выполнит запросы (при условии, что представление должно извлекать данные) со стороны сервера, а затем отправит клиенту обработанный HTML.

Поскольку apollo-client извлекает, а затем кэширует данные со стороны сервера, то возникает вопрос «Делает ли следующее. js отправляет apollo-client со своим кешем на сторону клиента для следующего запроса?»

  • Вы не можете быть уверены в этом, если не будете четко понимать, что такое Next.js и apollo-client cache (о его реализации или о том, как он работает внутри, если apollo кэширует данные в памяти на стороне сервера). , вы потерпите неудачу, если вы go таким образом)

  • Ответ не уверен , потому что это зависит от двух вещей одновременно. И, возможно, изменилось в будущем!

Итак, чтобы справиться с этой проблемой, просто используйте способ Next.js, он разработал туннель для данных, это query на url.

const NameForm = props => {
    const [name, setName] = useState("");
    const client = useApolloClient();
    const router = useRouter();

    const handleSubmit = e => {
        e.preventDefault();
        if(!name) return;
        router.push(`/user/register?name=${name}`);
    }
    //render ...
}

import { useRouter } from 'next/router';
import AddUserForm from '../../components/forms/AddUserForm';
const AddUser = () => {
    const router = useRouter();
    return (
        <React.Fragment>
            <AddUserForm name={router.query.name} />
        </React.Fragment>
    )
}
export default AddUser;

Если вы хотите отправить объект вместо строки?

const data = { name: "FoxeyeRinx", email: "foxeye.rinx@gmail.com" };
const base64 = btoa(JSON.stringify(data));
router.push(`/user/register?data=${base64}`);
const AddUser = () => {
    const router = useRouter();
    const base64 = router.query.data;
    //decode base64 then parse it to js object
    const data = JSON.parse(atob(base64)); 
    return (
        <React.Fragment>
            <AddUserForm data={data}/>
        </React.Fragment>
    )
}

Если вы думаете запрос уродлив и хотите скрыть запрос , используйте это руководство: https://nextjs.org/learn/basics/clean-urls-with-dynamic-routing

...