【问题标题】:I can't figure out how to define state and this.setState in react我不知道如何在反应中定义 state 和 this.setState
【发布时间】:2019-10-12 04:09:04
【问题描述】:

我正在关注如何将文本发布到 django rest api 服务器的教程。每个教程都说要使用 state 和 this.setState 来更新 api 表单并将其发送到服务器。但是经过大约两天的尝试,我无法弄清楚是什么问题。

我已经尝试过使用构造函数,将 App 设置为类而不是函数,并且在我能找到的每个教程中都搞砸了。我对此真的很陌生,所以这可能很明显。

这是我的 App.jsx


import React from 'react';

import './scss/sass.scss';

import './scss/customBootstrap.scss';

import 'react-bootstrap';

import axios from 'axios';

function App() {

    var fontWeight = {
        fontWeight: 'bold',
    };

    var backgroundColor = {
        backgroundColor: 'chartreuse'
    };

    function onClick() {
        console.log("Sending a GET API Call !!!");
        axios.get('http://127.0.0.1:8000/api')
        .then(res => {
            console.log(JSON.stringify(res))
        })
    };

    var state = { description: '' }

      function handleChange(e) {
        this.setState({
          [e.target.id]: e.target.value
        })
      };

      function handleSubmit(e) {
        e.preventDefault();
        console.log(this.state);
        let form_data = new FormData();

        form_data.append('description', this.state.description);
        let url = 'http://localhost:8000/api/';
        axios.post(url, form_data, {
          headers: {
            'content-type': 'multipart/form-data'
          }
        })
            .then(res => {
              console.log(res.data);
            })
            .catch(err => console.log(err))
      };

  return (


    <React.Fragment>

    <div className="container">

    <div className="row">

    </div>

    </div>


    <div className="container">

    <div className="row" style={backgroundColor}>

    <div className="col">
    <form className="search-bar">
    <input type="text" placeholder="Search"/>
    <button type="submit"></button>
    </form>

    </div>
    </div>

    </div>

    <div className="container">

    <div id="post" className="row">
    <div className="col">
    <form className="user-post">
    <textarea className="user-post" placeholder="Write a post here"></textarea>
    <button type="submit"></button>
    </form>
    </div>
    </div>

    <div id="content" className="row">
    <p className="link-text">Content will be here</p>
    </div>
//this is a get request that somehow works fine compared to the post request
    <div>
    <button type="button" onClick={onClick}>Send GET /products</button>
    </div>

//this is the tutorial text input form im trying to make work
    <form onSubmit={handleSubmit}>
    <p>
    <input type="text" placeholder='Description' id='description' value={this.state.description} onChange={handleChange} required/>
    </p>
    <input type="submit"/>
    </form>

    <div id="feedback" className="row">
    <div className="col">
    <form className="feedback" name="feedback">
    <textarea maxLength="335" className="feedback" placeholder="Write your feedback here"></textarea>
    <button type="submit"></button>
    </form>
    </div>
    </div>

    </div>


<footer>

</footer>

      </React.Fragment>
  );
}

export default App;

最后应该发生的是它将输入的文本发送到api,但是当我尝试从浏览器发送文本数据时,浏览器给我:“TypeError:无法读取未定义的属性'setState'”。

【问题讨论】:

    标签: javascript reactjs create-react-app


    【解决方案1】:

    这种混乱与 React 随时间的演变有关。长期以来,在 React 中使用状态的唯一方法是使用类组件和 this.setState 来更新它。这就是为什么它是您发现的大多数教程中的首选方法。

    class App extends Component {
      state = {
        //some state 
      }
      handleChange = () => {
        this.setState({
          // something has changed, update state.
        })
      }
      render() {
        return (
          // return some jsx
        );
      }
    }
    

    通过在您的类组件中扩展Component,您可以在其事件处理程序中使用this.setState 来更新状态并刷新UI。但是this 在你尝试过的功能组件中是不可能的。

    但是earlier this year(2019 年 2 月),React 引入了一种称为Hooks 的方法,可以在功能组件中用作状态。在Using the State hook中查看如何使用它

    您必须将类组件和this.setState 或函数组件和useState 混合使用,而不是混合这两种模式。

    【讨论】:

    • 谢谢! useState 和 Hooks 绝对是我要走的路。如果我还有任何问题,请多多包涵。 :)
    【解决方案2】:

    您的App 是一个功能组件。它没有有意义的this,所以不要尝试使用它。要么将其切换到类组件,要么改用useState

    【讨论】:

      【解决方案3】:
      import React, { Component } from 'react';
      import './scss/sass.scss';
      import './scss/customBootstrap.scss';
      import 'react-bootstrap';
      import axios from 'axios';
      import RenderAudioPopup from './client/src/App/components/Utility/RenderAudioPopup/RenderAudioPopup';
      
      class App extends Component {
          constructor(props) {
              super(props);
              this.state = {
                  fontWeight: 'bold',
                  backgroundColor: 'chartreuse',
                  description: ''
              }
          }
      
          onClick = async () => {
              console.log("Sending a GET API Call !!!");
              await axios.get('http://127.0.0.1:8000/api')
                  .then(res => {
                      console.log(JSON.stringify(res))
                  })
          }
      
          handleChange = async (e) => {
              this.setState({
                  [e.target.id]: e.target.value
              })
          }
          handleSubmit = async (e) => {
              e.preventDefault();
              console.log(this.state);
              let form_data = new FormData();
      
              form_data.append('description', this.state.description);
              let url = 'http://localhost:8000/api/';
              await axios.post(url, form_data, {
                  headers: {
                      'content-type': 'multipart/form-data'
                  }
              })
                  .then(res => {
                      console.log(res.data);
                  })
                  .catch(err => console.log(err))
          }
          render() {
      
              return (
                  <React.Fragment>
                      <div className="container">
                          <div className="row">
                          </div>
                      </div>
      
                      <div className="container">
                          <div className="row" style={this.state.backgroundColor}>
                              <div className="col">
                                  <form className="search-bar">
                                      <input type="text" placeholder="Search" />
                                      <button type="submit"></button>
                                  </form>
                              </div>
                          </div>
                      </div>
      
                      <div className="container">
                          <div id="post" className="row">
                              <div className="col">
                                  <form className="user-post">
                                      <textarea className="user-post" placeholder="Write a post here"></textarea>
                                      <button type="submit"></button>
                                  </form>
                              </div>
                          </div>
      
                          <div id="content" className="row">
                              <p className="link-text">Content will be here</p>
                          </div>
                          //this is a get request that somehow works fine compared to the post request
                          <div>
                              <button type="button" onClick={() => this.onClick()}>Send GET /products</button>
                          </div>
      
                          //this is the tutorial text input form im trying to make work
                          <form onSubmit={(e) => this.handleSubmit(e)}>
                              <p>
                                  <input type="text" placeholder='Description' id='description' value={this.state.description} onChange={(e) => this.handleChange(e)} required />
                              </p>
                              <input type="submit" />
                          </form>
      
                          <div id="feedback" className="row">
                              <div className="col">
                                  <form className="feedback" name="feedback">
                                      <textarea maxLength="335" className="feedback" placeholder="Write your feedback here"></textarea>
                                      <button type="submit"></button>
                                  </form>
                              </div>
                          </div>
      
                      </div>
      
                      <footer>
                      </footer>
                  </React.Fragment>
              );
          }
      
      }
      export default App;
      

      切换到Component类,如果是小组件则使用功能组件和useState设置值

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-27
        • 2020-01-09
        • 2018-10-19
        • 1970-01-01
        • 1970-01-01
        • 2015-08-06
        • 2015-09-11
        相关资源
        最近更新 更多