【问题标题】:How do I POST form data using Fetch and React?如何使用 Fetch 和 React 发布表单数据?
【发布时间】:2021-07-23 21:11:32
【问题描述】:

我正在使用 react 和 fetch 向我的本地 json 服务器提交发布请求。目标是在表单上提交“评论”并将其添加到 json 服务器。我的 json 文件似乎没有更新。我做错了什么?

import React, { Component } from 'react'
import './commentform.css';

class CommentForm extends Component {

    handleSubmit = (e) => {
        e.preventDefault()
        console.log('submitted')
    }
            

    render(){
        fetch('http://localhost:3001/comments', {
            method: 'POST',
            body: JSON.stringify(this.state)
            }).then(function(response) {
                console.log(response)
                return response.json()
                })
        return (
            <div>
            <h1>What is your favorite breed?</h1>
                <form onSubmit={this.handleSubmit}>
                    <label>Answer: </label><br/>
                    <textarea type="text" name="body"/><br/>
                    <input type="submit"/>
                </form>

            </div>
        )
    }
}

export default CommentForm

【问题讨论】:

  • 您没有处理 textarea 文本更改并将值设置为 state。而且,fetch 必须在 handleSubmit 中,而不是在 render 函数中。

标签: reactjs fetch jsx


【解决方案1】:

问题

最大的问题是您试图从 render 生命周期方法中发出 POST 请求,这在 React 中是非常反模式的。它应该在处理程序或常规生命周期方法中完成,例如 componentDidUpdate

当您提交表单时,您还会发送整个 state 对象...但您永远不会更新它。

解决方案

选项 1

保留不受控制的输入并访问提交处理程序中的表单字段。

class CommentForm extends Component {
  handleSubmit = (e) => {
    e.preventDefault();
    console.log("submitted");

    const body = e.target.body.value;

    fetch("http://localhost:3001/comments", {
      method: "POST",
      body: JSON.stringify(body)
    }).then((response) => {
      console.log(response);
      return response.json(); // do something with response JSON
    });
  };

  render() {
    return (
      <div>
        <h1>What is your favorite breed?</h1>
        <form onSubmit={this.handleSubmit}>
          <label>Answer: </label>
          <br />
          <textarea type="text" name="body" />
          <br />
          <input type="submit" />
        </form>
      </div>
    );
  }
}

选项2

转换为完全受控的输入并访问提交处理程序中的状态。您需要向 textarea 添加一个 value 属性和一个 onChange 处理程序以更新本地状态。

class CommentForm extends Component {
  state = {
    body: '',
  };

  handleSubmit = (e) => {
    e.preventDefault();
    console.log("submitted");

    const { body } = this.state;

    fetch("http://localhost:3001/comments", {
      method: "POST",
      body: JSON.stringify(body)
    }).then((response) => {
      console.log(response);
      return response.json();
    });
  };

  render() {
    const { body } = this.state;

    return (
      <div>
        <h1>What is your favorite breed?</h1>
        <form onSubmit={this.handleSubmit}>
          <label>Answer: </label>
          <br />
          <textarea
            type="text"
            name="body"
            value={body}
            onChange={e => this.setState({
              body: e.target.value
            })}
          />
          <br />
          <input type="submit" />
        </form>
      </div>
    );
  }
}

【讨论】:

  • 嗨德鲁-谢谢你!我尝试了这两个选项,但仍然无法让我的 JSON 服务器接收数据。有什么想法吗?
  • 出现错误 CommentForm.js:11 POST localhost:3000/comments 404(未找到)
  • 端口 3000 通常是你的 React 应用运行的默认端口。您的代码指向服务器的端口 3001。你确定你有所有正确的端口吗?
  • 所以我在使用您的代码后将其更改为正确的端口,但似乎仍然无法正常工作。任何其他想法为什么它不起作用?
  • @megcho 对不起,我正在度假。我们确实需要更多细节和上下文,只是说它不起作用并不是很有帮助。您是否缩小了无效的范围?您的应用正在发出 POST 请求,那么您是否通过网络选项卡验证了该请求正在发出,并且请求正文正确?您的服务器是否收到请求?如果是这样,那里是如何处理的?什么是请求处置(即响应状态、200 OK、404 等...)?我们尚未确定这是前端问题还是后端问题。
【解决方案2】:

我认为我们在这方面存在很多问题。

在任何事情之前: 你不应该把你的 fetch API 像这样放在 render() 方法中,你想在用户提交表单时发布数据,对吧?现在还没有发生,让我来帮你。

好的,我们走吧: 首先,this React tutorial is about adding State to a React Class Component。现在您已经了解了如何以正确的方式进行操作,我们看到您没有构造函数来初始化您的状态,那么您必须执行以下操作:

constructor(props) {
  super(props)
  this.state = { text: "" }
}

现在您有了一个状态对象,其中包含一个名为 text "" 的道具作为初始值。

下一步: 你想用 textarea 上的输入数据来改变这个状态,对吧?所以你需要一些东西来触发这个打字动作。 React 为我们提供了“onChange”事件,将输入的数据分配给您需要执行以下操作的状态:

<form onSubmit={this.handleSubmit}>
  <label>Answer: </label><br/>
  <textarea type="text" name="body" onChange={(e) => this.setState({ text: e.target.value })}/><br/>
  <input type="submit"/>
</form>

现在您正确地将键入的数据分配给您的状态。

即将完成: 当用户单击“提交”时,您想要发布处于状态的数据,该数据绑定到调用“handleSubmit”,实际上除了记录“提交”之外什么都不做。您想将 fetch API 放在此函数中,使其成为 asynchronous。你应该这样做:

handleSubmit = async (e) => {
  e.preventDefault()
  console.log('Submitting form')
  fetch('http://localhost:3001/comments', {
    method: 'POST',
    body: this.state.text
  }).then(function(response) {
    console.log(response)
    return response.json()
  })
  console.log('Form submitted.')
}

现在,当用户实际点击提交按钮时,您将发布您的数据。

只是一个快速警告: 您没有提供足够的代码来查看本地 json 服务器如何接收您的请求正文,因此您应该检查我提供数据的方式是否适合您。

【讨论】:

  • 非常感谢!我应用了您的代码,但似乎仍然无法发布评论。这就是我的 db.json 文件 { "cmets": [ ] }
  • 我将 db.json 文件更改为以下内容
  • { "cmets": [ { "id": 1, "body": "some comment" } ] }
猜你喜欢
  • 2023-03-17
  • 2018-03-20
  • 2022-11-16
  • 2016-05-13
  • 2017-09-23
  • 1970-01-01
  • 2021-12-19
  • 1970-01-01
  • 2021-06-25
相关资源
最近更新 更多