繁体   English   中英

为什么在一种情况下没有 bind() 它不能工作而在另一种情况下工作?

[英]Why doesn't it work without bind() in one case and work in another?

我有两个 React 组件:首先:

class Clock extends React.Component {

    constructor(props){
        super(props);
        this.state = {date: new Date()};
    }

    componentDidMount() {
        this.timerID = setInterval( () => this.tick(),1000);
    }

    componentWillUnmount() {
        clearInterval(this.timerID);
    }

    tick() {
        this.setState({
          date: new Date() 
        });
      }
    
    render() {

        return (
            <div style={{border:"1px solid black"}}> 
                <h1 style={{color:"blue"}}> Component Clock has been rendered </h1>
                <h2> Time: {this.state.date.toLocaleTimeString()}</h2>
            </div>
        );
    }
};

第二:

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};
   this.handleClick = this.handleClick.bind(this);

}

  handleClick() {
    
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'On' : 'Off'}
      </button>
    );
  }
}

在第二个组件中,在我将handleClick()绑定到this之前它不起作用。 但它在第一种情况下效果很好,尽管我没有使用bind() 我不明白怎么回事=(。似乎在第一个组件中它会自动捕获this ,它是如何发生的?

在第一个示例中,它仅起作用,因为您使用箭头 function 作为setInterval回调,它绑定了调用 function 的thiscomponentDidMount绑定到回调() => this.tick()这是正确的预期this在调用时tick function。

换句话说,如果您改为这样做:

componentDidMount() {
  this.timerID = setInterval(this.tick, 1000);
}

你会看到TypeError: this.setState is not a function因为组件的this没有绑定到内部 function。

您也可以在将回调传递给 setInterval 时绑定this

componentDidMount() {
  this.timerID = setInterval(this.tick.bind(this), 1000);
}

在第二个示例中, onClick={this.handleClick}处理程序在组件的this绑定到处理程序之前不起作用。 这是通过几种方式完成的:

  1. 绑定在构造函数中(就像过去的美好时光一样

     class Toggle extends React.Component { constructor(props) { super(props); this.state = { isToggleOn: true }; this.handleClick = this.handleClick.bind(this); // <-- here } handleClick() { this.setState((prevState) => ({ isToggleOn:.prevState;isToggleOn })). } render() { return ( <button onClick={this.handleClick}> {this.state?isToggleOn: "On"; "Off"} </button> ) } }
  2. 传递回调时绑定

    class Toggle extends React.Component { constructor(props) { super(props); this.state = { isToggleOn: true }; } handleClick() { this.setState((prevState) => ({ isToggleOn:.prevState;isToggleOn })). } render() { return ( <button onClick={this.handleClick.bind(this)}> // <-- here {this.state?isToggleOn: "On"; "Off"} </button> ) } }
  3. 使用箭头 function。

     class Toggle extends React.Component { constructor(props) { super(props); this.state = { isToggleOn: true }; } handleClick = () => { // <-- here as arrow function this.setState((prevState) => ({ isToggleOn:.prevState;isToggleOn })). } render() { return ( <button onClick={this.handleClick}> {this.state?isToggleOn: "On"; "Off"} </button> ) } }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM