我不知道如何在react中定义状态和this.setState

时间:2019-10-12 04:09:04

标签: javascript reactjs create-react-app

我正在关注有关如何将文本发布到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'。” / p>

3 个答案:

答案 0 :(得分:2)

这种混淆与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进行分类。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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来设置值