简体   繁体   English

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

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

I have got two React Components: First:我有两个 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>
        );
    }
};

And second:第二:

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>
    );
  }
}

In second component it doesn't work until I bind handleClick() to this .在第二个组件中,在我将handleClick()绑定到this之前它不起作用。 But it works perfectly in first case, although, I haven't use bind() .但它在第一种情况下效果很好,尽管我没有使用bind() I can't understand what's the matter =(. It seems that in first component it automatically captures this , how does it happen?我不明白怎么回事=(。似乎在第一个组件中它会自动捕获this ,它是如何发生的?

In the first example it only works because you used an arrow function as the setInterval callback which bound the this of the calling function, componentDidMount to be bound to the callback () => this.tick() which is the correct expected this in the tick function when it's called.在第一个示例中,它仅起作用,因为您使用箭头 function 作为setInterval回调,它绑定了调用 function 的thiscomponentDidMount绑定到回调() => this.tick()这是正确的预期this在调用时tick function。

In other words, if you had instead done:换句话说,如果您改为这样做:

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

You'd see the TypeError: this.setState is not a function as the component's this isn't bound to the inner function.你会看到TypeError: this.setState is not a function因为组件的this没有绑定到内部 function。

You could also just bind this when passing the callback to `setInterval:您也可以在将回调传递给 setInterval 时绑定this

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

In the second example the onClick={this.handleClick} handler doesn't work until the component's this has been bound to the handler.在第二个示例中, onClick={this.handleClick}处理程序在组件的this绑定到处理程序之前不起作用。 This is done in a few ways:这是通过几种方式完成的:

  1. Bound in constructor ( just like the good old days )绑定在构造函数中(就像过去的美好时光一样

     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. Bound when passing callback传递回调时绑定

    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. Using arrow function.使用箭头 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