对React中的未定义错误感到困惑

时间:2019-06-15 00:38:17

标签: javascript reactjs

为可能的简单问题表示歉意。我有一些React代码,我想记录我的api响应。 当我console.log(this.state.api_response_name)时,控制台记录响应。当我尝试使用api_response_name.name进行以下操作时,即使我的json中有一个name字段,我的控制台日志中也未定义。我的问题是为什么?我是JS和React的新手,如果这是一个超级琐碎的答案,并且对能很好地描述文章的链接感到高兴,则感到抱歉。我找不到任何有意义的东西。

import React, { Component } from 'react';
import { Button, Form } from "semantic-ui-react";
import { api31Call } from '../helpers';

export default class PulseInputForm extends Component {
    constructor(props) {
        super(props)
        this.state = {
            project: "",
            mode:'view',
            api_response_name:{},
            loading:false
        }
        this.handleChange = this.handleChange.bind(this)
        this.handleSave = this.handleSave.bind(this);
        this.handleEdit = this.handleEdit.bind(this);
    }

    handleChange(event) {
        this.setState({value: event.target.value});
    }
    handleSave() {
        this.setState({mode: 'view'});
      }

    handleEdit() {
        this.setState({mode: 'edit'});
      }

    renderInputField() {
      if(this.state.mode === 'view') {
        return <div>working</div>;
      } else {
        return (
            <p>
              <input
                onChange={this.handleChange}
                value="something else"
              />
            </p>
        );
      }
    }

    renderButton() {
      if(this.state.mode === 'view') {
        return (
            <button onClick={this.handleEdit}>
              Edit
            </button>
        );
      } else {
        return (
            <button onClick={this.handleSave}>
              Save
            </button>
        );
      }
    }

    componentDidMount() {
      this.setState({loading: true})
      // not_localized = hard coded project 
        api31Call('GET', '/projects','/not_localized')
            .then(data => {
              this.setState({
                loading: false,
                api_response_name: data
              })
            })
      }

    render() {  
        const text = this.state.loading ? "loading..." : console.log(this.state.api_response_name.name)     
        return (
        <div>
        <Form >
            <Form.Field>
                <label>Project</label>
                <input name="project" placeholder="Your Project" onChange={this.handleChange} />
            </Form.Field>
            <Form.Field>
                <label>Timeframe</label>
                <input placeholder="Integer e.g. 50 (Max 90 Days)" />
            </Form.Field>
          {text}
          {this.renderInputField()}
          {this.renderButton()}
         </Form> 

        </div>
        )
      }
}

1 个答案:

答案 0 :(得分:0)

componentDidMount()方法在组件输出呈现到DOM之后运行。(您可以了解React生命周期here)。因此,在组件的第一次呈现中,{{1}中没有任何内容},并且状态与您在api_response_name中定义的状态相同。但是在将组件安装到DOM之后,将调用函数constructor并使用此代码

componentDidMount()

已执行。因此,状态更改后,您在api_response_name中有了名称。但是,在挂载一次调用的渲染函数之前,此时componentDidMount() { this.setState({loading: true}) // not_localized = hard coded project api31Call('GET', '/projects','/not_localized') .then(data => { this.setState({ loading: false, api_response_name: data }) }) } 等于this.state.api_response_name。因此,此时您将获得一个异常,并且您的组件将崩溃。但是,您可以在构造函数中将{}设置为loading,那么一切都会好起来的。因为,然后在第一个渲染中,falseloading,文本仅等于false,并且在挂载loading之后执行,并且在api调用之后,您的状态正确更改,并且组件将完美运行。