首页 > React的一个报错?

React的一个报错?

页面上是个用户注册的表单,刚刷新的时候不会报错,一旦开始输入就会报错,报错信息如图:


想必就是handleChange()函数报错了

请问错在哪呢?


首先说一下你排除错误的方法,因为用react你会经常遇到Cannot read property 'xxxxx' of undefined这个错误,那么你想没想过console.log一下那个undefined的东西,并一路回溯回去找到他呢?

然后再来谈你这个问题的错误。这是一个js从娘胎里带来的毛病,我知道你肯定是这么写component的

class YourClass extends React.Component{
    constructor(props){
        super(props)
        this.state={}
    }
    
    handleChange(e){
        //.......
    }
}

你在handleChange函数里面console.log(this)一下,会发现这个this是null,而不是你期待的YourClass,setState是YourClass从React.Component继承来的,null自然不会有setState这个方法。

那么就意味着你必须把外面的this指针传入handleChange函数里面。有大概三种方法
1、在调用的时候,看你这个情况应该是类似input或者textarea调用onChange方法时候调用的吧,原来你应该是这么写的:<input onChange={this.handleChange} />,把他改写成<input onChange={this.handleChange.bind(this)} />,这样,this指针就被传进去啦。
2、把handleChange函数用箭头函数的方式改写为

handleChange = (e) =>{
    //.....内容不变
}
这样改写出来的函数会被自动bind上他所处的class的this指针。调用的时候原样调用即可。

3、类似方法1,好像看到还有一种<input onChange={::this.handleChange}/>的写法,作用一样,相当于语法糖,应该还需要babel配合一些plugin来支持,所以可以忽略这个方法,上面两种就够用了


说的很清楚了
this是undefined的
onChange的时候 this.handleChange.bind(this)一下就好了


@cheoyx 作用域的问题已经解决了,但有个新的问题,在表单内输入的时候,输入框里完全是空的,没有反应,也完全没报错,不知道怎么回事,应该怎么排查?以下是该组件的全部代码,如果有其他问题也欢迎提点,谢谢~~

import React, { Component } from 'react';

class Signup extends Component {
  constructor(props){
      super(props);
        this.state = {
      username: '',
      nick: '',
      password: ''
    };
    this.handleClick = this.handleClick.bind(this);
    this.handleChange = this.handleChange.bind(this);
    };
  handleChange(e) {
      this.setState({value: event.target.value});
  };
  handleClick() {
      let data = {
          username : this.state.username,
          nick: this.state.nick,
          password : this.state.password,
      }
      console.log(data);
  };
  render() {
    let styles = {
      signPagesStyle: {
        display: 'flex',
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        flexShrink: 0
      },
      inputPosition: {
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center'
      },
      inputMargin: {
        margin: '20px 0'
      },
      buttonStyle: {
        backgroundColor: '#03A9F4',
        boxShadow: '0px 1px 6px rgba(0, 0, 0, 0.117647), 0px 1px 6px rgba(0, 0, 0, 0.117647)',
        color: '#ffffff',
        fontSize: '16px',
        width: '160px',
        height: '36px',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center'
      }
    }
    return (
      <div style={styles.signPagesStyle}>
        <div style={styles.inputPosition}>
          <div style={styles.inputMargin}>
            <input type="text" onChange={this.handleChange} value={this.state.username} />
          </div>
          <div style={styles.inputMargin}>
            <input type="text" onChange={this.handleChange} value={this.state.nick} />
          </div>
          <div style={styles.inputMargin}>
            <input type="text" onChange={this.handleChange} value={this.state.password} />
          </div>
          <div style={styles.buttonStyle} onClick={this.handleClick}>注册</div>
        </div>
      </div>
    )
  }
}

export default Signup;

把你调用handleChange的地方改改,我猜你现在是这么用的:

{ this.handleChange }

改成:

{ this.handleChange.bind(this) }

通常这个问题出现,是因为用了ES2015 class,里面的no autobinding

【热门文章】
【热门文章】