TypeError:无法读取未定义的属性“ handleClick”

时间:2019-07-16 15:26:51

标签: javascript html reactjs

我正在学习React,并且正在尝试做一个小项目。该项目正在显示jsonPlaceholder的用户列表,并希望使其编辑字段。

我有一个用于加载列表的div,另一个具有可编辑字段的隐藏div,还有一个按钮,当单击列表div时该按钮被隐藏,另一个按钮出现。

当我单击按钮时,出现以下错误:

  

“ TypeError:无法读取未定义的属性'handleClick'”

有人可以帮忙吗?

import React from 'react';
import './App.css';

class User extends React.Component {
  constructor(){
    super();
    this.state = {
      users: [],
      displayList: 'block',
      displayForm: 'none'
    }
    this.handleClick = this.handleClick.bind(this);
  }

  componentDidMount(){
    this.getUsers();
  }

  getUsers(){
    fetch('https://jsonplaceholder.typicode.com/users')
      .then(response  => response.json())
      .then(json => this.setState({users: json}));
  }

  handleClick(){
    this.setState({displayList: 'none', displayForm: 'block'})
  }

  render(){
    const list = this.state.displayList;
    const form = this.state.displayForm;

    return (
      <ul>
        {this.state.users.map(function(item){
          return (
            <div key={item.id}>
              <br></br>

              <div style={{display: list}}>
                <h2>{item.name} </h2>
                <p>Email: {item.email} </p>
                <p>Address: </p>
                <ul>
                  <li>Street: {item.address.street} </li>
                  <li>Suite: {item.address.suite} </li>
                  <li>City: {item.address.city} </li>
                  <li>ZipCode: {item.address.zipcode} </li>
                </ul>
                <p>Phone: {item.phone} </ p>
              </div>

              <div style={{display: form}} >
                <div>
                  <h2>{item.name} </h2>
                  <p>Email: <input value = {item.email} className="form-control" onChange=""/> </p>
                  <p>Address: </p>
                  <ul>
                    <li>Street: <input value = {item.address.street} className="form-control" /> </li>
                    <li>Suite: <input value = {item.address.suite} className="form-control" /> </li>
                    <li>City: <input value = {item.address.city} className="form-control" /> </li>
                    <li>ZipCode: <input value = {item.address.zipcode} className="form-control" /> </li>
                  </ul>
                  <p>Phone: <input value = {item.phone} className="form-control" /> </p>
                </div>
              </div>

              <button onClick={() => this.handleClick()}> Edit </button>
              <hr></hr>
            </div>
          )
        })}
      </ul>
    );
  }
}

export default User;

3 个答案:

答案 0 :(得分:2)

这是因为未绑定映射方法this.state.users.map中的回调。您需要将其变成箭头功能。像这样:

import React from 'react';
import './App.css';

class User extends React.Component {
  constructor(){
    super();
    this.state = {
      users: [],
      displayList: 'block',
      displayForm: 'none'
    }
    this.handleClick = this.handleClick.bind(this);
  }

  componentDidMount(){
    this.getUsers();
  }

  getUsers(id){
    fetch('https://jsonplaceholder.typicode.com/users')
      .then(response  => response.json())
      .then(json => this.setState({users: json}));
  }

  handleClick(){
    this.setState({displayList: 'none', displayForm: 'block'})
  }

  render(){
    const list = this.state.displayList;
    const form = this.state.displayForm;

    return (
      <ul>
        {this.state.users.map((item => {
          return (
            <div key={item.id}>
              <br></br>

              <div style={{display: list}}>
                <h2>{item.name} </h2>
                <p>Email: {item.email} </p>
                <p>Address: </p>
                <ul>
                  <li>Street: {item.address.street} </li>
                  <li>Suite: {item.address.suite} </li>
                  <li>City: {item.address.city} </li>
                  <li>ZipCode: {item.address.zipcode} </li>
                </ul>
                <p>Phone: {item.phone} </ p>
              </div>

              <div style={{display: form}} >
                <div>
                  <h2>{item.name} </h2>
                  <p>Email: <input value = {item.email} className="form-control" onChange=""/> </p>
                  <p>Address: </p>
                  <ul>
                    <li>Street: <input value = {item.address.street} className="form-control" /> </li>
                    <li>Suite: <input value = {item.address.suite} className="form-control" /> </li>
                    <li>City: <input value = {item.address.city} className="form-control" /> </li>
                    <li>ZipCode: <input value = {item.address.zipcode} className="form-control" /> </li>
                  </ul>
                  <p>Phone: <input value = {item.phone} className="form-control" /> </p>
                </div>
              </div>

              <button onClick={this.handleClick}> Edit </button>
              <hr></hr>
            </div>
          )
        }))}
      </ul>
    );
  }
}

export default User;

答案 1 :(得分:0)

问题是this.handleClick在定义为常规function的回调中被引用,该回调传递给map。常规函数的their own values中的this不是组件。

为了进行retain the value of this调用,您需要将回调函数作为箭头函数传递给地图:

render () {
    /* ... */
    return (
      <ul>
        {this.state.users.map((item) => { /* ... */ })}
      </ul>
    )
}

或者,您可以将this值作为第二个参数显式传递给map

render () {
    /* ... */
    return (
      <ul>
        {this.state.users.map(function(item) { /* ... */ }, this)}
      </ul>
    )
}

答案 2 :(得分:0)

您必须将方法绑定到对象。

要么:

handleClick = () => {
    this.setState({displayList: 'none', displayForm: 'block'})
}

或:

<button onClick={this.handleClick.bind(this)}> Edit </button>

否则,它将失去上下文。