ReactJS-TypeError:无法设置未定义的属性“ propOne”

时间:2019-12-28 21:35:02

标签: javascript reactjs

我有一个简单的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:无法设置未定义属性'propOne'错误

3 个答案:

答案 0 :(得分:2)

这是因为您要创建新函数并创建this的新实例。将其更改为箭头功能-

 handleChange = (event) => {

    this.propOne = event.target.value;
  }

或者您可以在类的构造函数中将this的{​​{1}}绑定到父级的handleChange

this

答案 1 :(得分:1)

对@Atin表示感谢,他提到将您的handleChange函数更改为箭头函数或绑定了this(我将在答案中使用arrow函数)。

您还需要将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} /> </> ); } ,如下所示:

#include <https://raw.githubusercontent.com/Quuxplusone/coro/master/include/coro/shared_generator.h>
#include <stdio.h>
#include <tuple>
#include <range/v3/view/take.hpp>

namespace rv = ranges::view;

auto triples() -> shared_generator<std::tuple<int, int, int>> { 
    for (int z = 1; true; ++z) {
        for (int x = 1; x < z; ++x) {
            for (int y = x; y < z; ++y) {
                if (x*x + y*y == z*z) {
                    co_yield std::make_tuple(x, y, z);
                }
            }
        }
    }
}

int main() {
    for (auto&& triple : triples() | rv::take(10)) {
        printf(
            "(%d,%d,%d)\n",
            std::get<0>(triple),
            std::get<1>(triple),
            std::get<2>(triple)
        );
    }
}

答案 2 :(得分:0)

由于未绑定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') )而引发了参考错误。

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

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script><div id="root"></div>
string connectionString = "server=myServer;User ID=myUser;Password=myPwd;"; // could also be internal static on class level

string theQuery = "SELECT * FROM dbo.Users WHERE Username = @userName AND Password = @password";

using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
    sqlConnection.Open();

    using (SqlCommand sqlCommand = new SqlCommand(theQuery, sqlConnection))
    {
        sqlCommand.Parameters.AddWithValue("@userName", textBox1.Text);
        sqlCommand.Parameters.AddWithValue("@password", textBox2.Text);

        DataTable dataTable = new DataTable();
        dataTable.Load(sqlCommand.ExecuteReader());
        if (dataTable.Rows > 0)
        {
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
            sqlDataAdapter.Fill(dataTable);
        }
    }
}

p.s。而且我也同意以上答案,功能组件和挂钩可以使您的应用看起来更好