【问题标题】:ReactJS - TypeError: Cannot set property 'propOne' of undefinedReactJS - TypeError:无法设置未定义的属性'propOne'
【发布时间】:2019-12-28 21:35:02
【问题描述】:

我有一个简单的 React 组件:

import React from "react";

export default class Car extends React.Component {
  render() {
    return <h2>I am a {this.props.name}</h2>;
  }
}

然后我将此组件导入另一个组件。这个新组件有一个文本框,其中 onChange 事件尝试设置一个属性,该属性作为属性传递给组件一。

import React from "react";
import Car from "./Car";

class Garage extends React.Component {
  constructor(props) {
    super(props);
    this.propOne = "Ford";
    this.state = { value: "initial Value" };
  }

  handleChange(event) {

    this.propOne = event.target.value;
  }
  render() {
    return (
      <>
        <input
          type="text"
          value={this.state.value}
          onChange={this.handleChange}
        />
        <Car name={this.propOne} />
      </>
    );
  }
}

export default Garage;

运行此代码后,我收到 TypeError: Cannot set property 'propOne' of undefined 错误

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    这是因为您正在创建一个新函数并创建一个 this 的新实例。改成箭头函数-

     handleChange = (event) => {
    
        this.propOne = event.target.value;
      }
    

    或者你可以在类的构造函数中将handleChangethis绑定到父级的this

    constructor(props) {
        super(props);
        this.propOne = "Ford";
        this.state = { value: "initial Value" };
    
        this.handleChange = this.handleChange.bind(this);
      }
    

    【讨论】:

    • 这可行,但我仍然无法将新值(在 onChange 事件期间设置)传递给 car 组件。投票支持修复错误。
    • @OpenStack,您可能可以更新道具,但组件没有被重新渲染,因为它不是通过setState完成的
    【解决方案2】:

    感谢 @Atin 提到将您的 handleChange 函数更改为箭头函数或绑定 this(我将在回答中使用箭头函数)。

    您还需要将propOne 设置为状态,并使用this.setState(...) 更新propOne 的值,以便您的组件在propOne 更改时重新呈现。当您只是更改 this.propOne 时,React 并不知道您的组件需要使用更新后的值重新渲染,这就是您在 Car 中看不到效果的原因。 -> 这就是state 的用途。每当 state 更改(使用 this.setState)时,React 知道它需要重新渲染该组件,并将更新后的 state 属性传递给子组件。

    试试这个state

    this.state = { value: "initial Value", propOne: "Ford" };
    

    这适用于您的handleChange 功能:

    handleChange = (event) => {
        this.setState({ propOne: event.target.value });
    }
    

    编辑

    此外,您的代码(以及上面的固定代码)正在状态上设置属性propOne,但您使用this.state.value 来更新您的input 文本值。您是否有任何理由尝试使用两个不同的属性 - valuepropOne?似乎它们被用于相同的目的,因此您可以在任何地方将 propOne 替换为 value,如下所示:

    constructor(props) {
        super(props);
        this.state = { value: "initial Value" };
    }
    
    handleChange = (event) => {
        this.setState({ value: event.target.value });
    }
    
    render() {
        return (
            <>
                <input
                    type="text"
                    value={this.state.value}
                    onChange={this.handleChange}
                />
                <Car name={this.state.value} />
            </>
        );
    }
    

    【讨论】:

      【解决方案3】:

      由于您没有绑定this,因此引发了引用错误。

      除此之外,您的代码中还有很多错误,因此我尝试一次性解决所有问题。如果您还有其他问题,请随时在 cmets 中提问:

      const { render } = ReactDOM
      
      class Car extends React.Component {
        render() {
          return <h2>I am a {this.props.name}</h2>
        }
      }
      
      class Garage extends React.Component {
        constructor(props) {
          super(props)
          this.handleChange = this.handleChange.bind(this)
          this.state = { value: "initial Value", propOne: 'Ford' }
        }
      
        handleChange(val) {
          this.setState({value: val, propOne: val})
        }
        
        render() {
          return (
            <div>
              <input
                type="text"
                value={this.state.value}
                onChange={e => this.handleChange(e.target.value)}
              />
              <Car name={this.state.propOne} />
            </div>
          )
        }
      }
      
      render(
        <Garage />,
        document.getElementById('root')
      )
      &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"&gt;&lt;/script&gt;&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"&gt;&lt;/script&gt;&lt;div id="root"&gt;&lt;/div&gt;

      附言我同意上面的答案,函数组件和钩子可以让你的应用看起来更好

      【讨论】:

        猜你喜欢
        • 2015-09-09
        • 2021-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-20
        • 2020-10-02
        相关资源
        最近更新 更多