Я не могу понять, как определить состояние и this.setState в реакции - PullRequest
0 голосов
/ 12 октября 2019

Я следую учебному пособию о том, как публиковать текст на сервере django rest api. В каждом уроке говорится, что нужно использовать state и this.setState, чтобы обновить форму API и отправить ее на сервер. Но примерно после двух дней попыток я не могу понять, что не так.

Я уже пытался использовать конструктор, устанавливая приложение в класс вместо функции и разбираясь с вещами в каждомучебник я могу найти. Я действительно новичок в этом, так что это, вероятно, что-то очевидное.

Вот мой 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 из undefined».

Ответы [ 3 ]

2 голосов
/ 12 октября 2019

Эта путаница связана с эволюцией Реакта с течением времени. Долгое время единственным способом использовать состояние в 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 внутри их обработчиков событий для обновления состояния и обновления пользовательского интерфейса. Но this невозможно в функциональном компоненте, как вы пытались.

Но ранее в этом году (февраль 2019), React ввел способ, называемый Hooks это может использоваться как состояние в функциональных компонентах. Посмотрите, как это использовать в Использование хука состояния

Вместо того, чтобы смешивать оба этих шаблона, вам придется либо использовать компонент класса и this.setState, либо функциональный компонент и useState.

0 голосов
/ 12 октября 2019
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, чтобы установить значение

0 голосов
/ 12 октября 2019

Ваш App является функциональным компонентом. У него нет значимого this, поэтому не пытайтесь его использовать. Либо переключите его на компонент класса, либо используйте useState.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...