react-hooks - 如何使用 Apollo 和 NextJS 将数据转发到下一页
问题描述
我正在使用 NextJS、Apollo 和 React(钩子)开发一个 Web 应用程序。
我有一个表格,要求访客姓名作为注册过程的第一步。提交表单时,名称将保存在 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 中做到这一点,钩子只允许在功能组件的主体中。
由于 next、react hooks 和 apollo 的不断发展,我缺少有关此的教程/课程,我发现很难找到正确的方法来做到这一点。
我希望这里有人可以进一步帮助我。
解决方案
使用 apollo-client 缓存可能会导致您遇到一些真正取决于apollo-client
的实现和nextjs
实现的问题。如果您通过在浏览器地址栏中输入 url 打开您的应用程序,Next.js
将从服务器端发出请求(假设视图需要获取数据),然后将呈现的 HTML 发送到客户端。
因为apollo-client
fetch 然后从服务器端缓存数据,所以问题是“Next.js 是否将带有缓存的 apollo-client 发送到客户端以进行下一个请求?”
你不能确定这一点,除非你清楚地了解
Next.js
和apollo-client cache
(关于它的实现或它如何在内部工作,如果apollo
在服务器端缓存数据在内存中,如果你这样做,你会失败)答案是不确定的,因为它同时取决于两个东西。未来可能会改变!
所以为了处理这个问题,就用这种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
推荐阅读
- python - 将文本从 tkinter 文本框保存到 .doc 文件时,如何保持格式?
- excel - 为什么我的 SSRS 生成的大型 excel (XLSX) 文件无法打开?
- c# - 有没有办法将“Globals.ThisAddIn”的引用从 MS Word 加载项传递到同一解决方案中的 WinForms 项目?
- reactjs - 使用 GitHub Actions 和 Firebase 时,Jest 在测试运行完成后一秒没有退出
- java - 在 Spring Boot 应用程序中登录后维护用户的会话(HttpSession)
- c# - Random.Next 确实有效,但它不会返回每个值
- ios - 使用 Firebase 和 Swift 存储独特的事件
- r - 从可能的标签库中为数据框分配标签
- gtk3 - 如何监控 Gtk3 事件循环延迟
- oracle - Oracle APEX Page item Read Only option which have multiple Conditions