web-dev-qa-db-ja.com

ReactJSは未定義のプロパティsetStateを読み取れません

私はReactJSを使い始めたばかりですが、この質問がSOFの数値質問に複製されることを多少理解しています。

しかし、誰かが私にReactのいくつかの概念についていくつかの指示と明確化を提供できることを願っています。

私がやりたいのは、画面が読み込まれる前に、リモートからREST axiosまたは_isomorphic-fetch_を使用してAPIからデータを取得することです。

しかし、私はよく似たReactチュートリアルをたくさん見ましたが、それでもポイントがわかりませんでした。

これが私のコードです:

_import React, { Component } from 'react';
import axios from 'axios'

// import InputRow from './components/InputRow';
import './App.css';

// require('es6-promise').polyfill();
// require('isomorphic-fetch');

class App extends Component {

        constructor(props) {
                super(props);

                const app_id = '<my_app_id>';

                const version = 0.1;
                this.luisURL = `https://westus.api.cognitive.Microsoft.com/luis/api/v2.0/apps/${app_id}/versions/${version}`;

                // this.getLUISIntent = this.getLUISIntent.bind(this);

                this.state = {
                        intentOptions: [],
                        utterance: '',
                        intent: ''
                };
        }

        getLUISIntent = () => {
                const subscription_key = '<my_subscription_key>';

                const URL = this.luisURL + '/intents';

                return axios.get(URL, {
                        headers: {
                                "Content-Type": 'application/json',
                                "Ocp-Apim-Subscription-Key": subscription_key
                        },
                })
                .then(function(res){
                        this.setState({intentOptions: res.data});
                });
        }

        componentWillMount = () => {
                // this.setState({
                //      intentOptions: this.getLUISIntent()
                // });
        }

        componentDidMount = () => {
                this.getLUISIntent();
        }

        componentDidUpdate = (prevProps, prevState) => {
                console.log("state: ", this.state);
                // this.submitToLUIS();
        }

        shouldComponentUpdate = (nextProps, nextState) => {
                return true;
        }

        submitToLUIS = () => {
                console.log("Submit to LUIS: ", this.state);
        };

        setIntent = (e) => {
                this.setState({intent: e.target.value});
        };

        setUtterance = (e) => {
                this.setState({utterance: e.target.value});
        };

        render() {
                return (
                        <div className="App">
                                <div className="container">
                                        <div className="row">
                                                <div className="col-sm-4">Utterance</div>
                                                <div className="col-sm-4">Intent</div>
                                                <div className="col-sm-4"></div>
                                        </div>
                                        <div className="row">
                                                <div className="col-sm-4">
                                                        <input className="form-control utterance" type="text" onChange={this.setUtterance} />
                                                </div>
                                                <div className="col-sm-4">
                                                        <select className="form-control intent" onChange={this.setIntent}>
                                                                <option key="intent_defualt" value="">Select...</option>
                                                                {this.state.intentOptions.map((obj, i) =>
                                                                        <option key={obj.id} value={obj.id}>{obj.name}</option>
                                                                )}
                                                        </select>
                                                </div>
                                                <div className="col-sm-4">
                                                        <button className="btn btn-primary" onClick={this.submitToLUIS}>Create</button>
                                                </div>
                                        </div>
                                </div>
                </div>
        );
        }
}

export default App;_

ここに私の質問があります:

  • UI全体を表示する前にリストをロードしたいのですが、このコードには何が欠けていますか?
  • getLUISIntentでアロー関数を使用することはここで正しいですか?
  • _async/await_をgetLUISIntent()で使用できますか?
  • 私にとって、_async/await_は、次の「行」を実行する前に関数からの応答を待つことを意味します。この概念は正しいですか?
  • クラス関数を使用するために追加のthis.__my_fancy_function__ = this.__my_fancy_function__.bind(this)を作成する必要がある場合、矢印関数を使用するとコードが少なく読みやすくなるようですが、誰もがそれを使用しないのはなぜですか?
  • _Fetch remote API before loading anything using ReactJS tutorial no splitting different component but showing everything in only single App.js No BS so that everyone can see how a REST API-simple ReactJS app is run_チュートリアルはありますか?そんなものがなければ書きたいと思います。しかしその前に、誰かが私の考えを最初に明確にしてくれることを願っています。

よろしくお願いします。

4
Ellery Leung

ajaxリクエストからのコールバック関数はバインドされていません。関数を別の関数に(コールバックとして)渡す場合、「this」は、それを書いたときとは対照的に、最終的に呼び出されたときのコンテキストへの参照になります。アロー関数を使用すると、記述したときのコンテキストが保持されます。

.then(function(res){
        this.setState({intentOptions: res.data});
    });

この関数を矢印関数にすると、問題は解決されます。

.then((res) => this.setState({intentOptions: res.data}));
16
Jason Spradlin