【问题标题】:How to return API (fetched) data from Formik Submit in Next.js如何从 Next.js 中的表单提交返回 API(获取)数据
【发布时间】:2019-09-14 08:42:13
【问题描述】:

我是新的@frontend,发现使用FormikNext.js 创建一个简单的搜索表单并返回从我自己的API 获取的数据返回页面有点困难。由于没有太多相关信息,或者没有,但它没有涵盖整个过程,所以我决定创建这个问题。

我在处理什么:

  1. 在 express 上分离基于前端和后端的 API(两者都在 本地主机)
  2. React (+ dom) & Next.js
  3. React Material-UI
  4. 福米克

架构:

前端发送请求(基于表单输入)-> 服务器接收到它(对其进行操作)并以json 对象响应-> 前端接收它,并将结果显示在页面上。

  • 后端(启用正确的 CORS)

当你像./users/100一样请求它时,一个简单的node.js快速服务器具有单路由(localhost:port/users/:id),它返回json,增加{id}+1,比如{id:101},下面的示例代码:

var express = require('express');
var router = express.Router();

/* CORS ARE FINE */
router.get('/:id', function(req, res) {
  res.json({id: parseInt(req.params.id)+1});
});

module.exports = router;

  • 前端(next.js + formik)

我已经编写了MyForm 组件并将其插入我的主页。这是MyForm组件的代码:

import React from 'react';
import fetch from 'isomorphic-unfetch'
import { Formik, Form, Field } from 'formik';
import { TextField } from 'formik-material-ui';
import Button from "@material-ui/core/Button";

const MyForm = () => (
    <Formik
        initialValues={{ text: '', password: '' }}
        onSubmit={ async (values, { setSubmitting }) => {
            const res = await fetch(`http://localhost:8000/users/${values.text}`, {
                method: 'GET',
                mode: 'cors',
                headers: {
                    'Content-Type': 'application/json',
                    'Access-Control-Allow-Origin': '*'
                }}).then(response => response.json());
            console.log(res);
            //props = res;
            //return props;
            setTimeout(() => {
                alert(JSON.stringify(res, null, 2));
                setSubmitting(false);
            }, 400);
        }}
    >
        {({ isSubmitting }) => (
            <Form>
                <Field
                    name="text"
                    label="Text"
                    type="text"
                    variant="outlined"
                    component={TextField}
                />
                <Button
                    type="submit"
                    variant="contained"
                    color="primary"
                    disabled={isSubmitting}
                >
                    Submit
                </Button>
            </Form>
        )}
    </Formik>
);

export default MyForm

就目前而言,myForm 工作正常,通过提交表单从 API 接收到必要的数据。结果存储为res 变量并在页面上显示为弹出窗口。

但我想看看它,回到页面上。像这样:

网络上没有太多教程逐步介绍此过程。我知道在Next.js fetched data received 通过getInitialProps。 (但是没有表单提交的例子)

我将组件放在页面上:

export default function Index() {
  return (
    <Container maxWidth="sm">
      <Box my={4}>
        <Form />
        <Here is an element with search form results />
      </Box>
    </Container>
  );
}

然后I read that I can't return props from child component 回到父级。或者我可以吗?我也不能将 res 变量作为组件值放在我的表单内部或外部:

那我现在应该怎么办?无论如何,我在Formik 教程中没有找到任何相关示例。我知道它与state 操作(如componentDiDMount)有某种联系,这就是前端开发人员使用Redux 等模块的原因。但是谁能解释一下,我做错了什么?

另外,如果您有任何相关信息并想给我一些建议或分享(例如 Formik 在这种情况下无用,您应该改用X),不要害羞,发布它。我会检查并投票。

根据@Shyam 的回答,我更新了我的代码。就目前而言,form 的代码如下:

const MyForm = (props) => (
    <Formik>
    ...
            onSubmit={ async (values, { setSubmitting }) => {
            const res = await fetch(`http://localhost:8000/users/${values.text}`, {
                method: 'GET',
                mode: 'cors',
                headers: {
                    'Content-Type': 'application/json',
                    'Access-Control-Allow-Origin': '*'
                }}).then(response => response.json());
            console.log(res);
            setSubmitting(false);
            props.myCallbackFunction(res);
        }}
    ...

index.js根据以下推荐,

在这种情况下,React 向我返回一个错误,与props 连接,但表单提交工作正常。我想我可以在这里找到相关信息:

https://reacttricks.com/sharing-global-data-in-next-with-custom-app-and-usecontext-hook/

【问题讨论】:

    标签: javascript reactjs next.js formik


    【解决方案1】:

    一种方法是将回调函数作为道具发送到 MyForm,并在收到获取的结果后使用 res 调用它。

    export default function Index() {
      const [result, setResult] = useState(null)
      const callMeOnRes = (data) => {
         setResult(data)
      }
      return (
        <Container maxWidth="sm">
          <Box my={4}>
            <Form myCallbackFunction={(res) => callMeOnRes(res)} />
            {result && <div>{result}</div>}
            <Here is an element with search form results />
          </Box>
        </Container>
      );
    }
    

    在 MyForm 中,在控制台日志之后调用props.myCallbackFunction(res)

    最好的方法是将 api 调用和前端逻辑解耦,并使用一些状态管理来加载、错误、调用状态。理想情况下,您不应该在这种情况下使用 setTimeouts。

    希望这会有所帮助。

    【讨论】:

    • 谢谢,我马上去看看。至于带有setTimeoutalert 框(仅)为我准备,只是为了确保API 的结果已返回并以human-like 的形式正确显示。我不会在我的最终项目中使用这种模式。
    • 在这种情况下const [result, setResult] = useState(null) useState 是什么?我应该从某个地方导入它吗?
    • useState 来自反应。您可以像 React.useState 或顶部的常规导入一样使用它。 import React, {useState} from React 并使用它。当此状态更新时,将再次调用完整函数,从而更新结果。
    • y,我用谷歌搜索了它,似乎它来自新的React Hooks,至于现在我的props.myCallbackFunction(res); 有错误,上面写着props are not defined。但形式工作正常。那么我应该如何正确定义它们呢? //我刚刚在我的问题结束时更新了有关props 的信息。
    • 它现在应该与(props) in MyForm 一起工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-03
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    • 2015-05-31
    相关资源
    最近更新 更多