【问题标题】:Are react's lifecycle method autobound? If not should we be binding them with .bind(this)?react 的生命周期方法是自动绑定的吗?如果不是,我们应该用 .bind(this) 绑定它们吗?
【发布时间】:2018-03-26 22:42:22
【问题描述】:

我认为标题非常自我描述。

我使用类表示法构建反应组件,我注意到虽然handleSomething 必须手动绑定到this,但rendercomponentWillMount 不需要。方法是否已经绑定到this?为了符号一致性,可以手动绑定吗?

【问题讨论】:

  • 不,它们没有被绑定,它们只是作为方法被调用?
  • 那么他们如何访问this.propsthis.state?他们是否无权访问绑定方法可以访问的权限?
  • 我不明白。当你调用component.render()(React 会这样做)时,render 内部的this 将引用component 并可以访问它的.state.props 属性。当你打电话给component.render.call(null),那就不行了。
  • 组件中的所有方法都完全相同,与handlers 的区别在于您使用函数引用传递它们。例如onClick={this.handleClick} 默认情况下它不绑定任何东西,这就是你需要绑定它的原因。如果你要这样称呼它component.handleClick(),那么你就不需要了。

标签: javascript reactjs ecmascript-6 es6-class


【解决方案1】:

理解 JavaScript 中的“this”

函数中的'this'关键字由函数的执行范围决定。例如,使用obj.someFunction() 调用时,someFunction 中的this 将是obj

一个更具体的例子:

function handleClick() {
    console.log(this.state.value);
}

var state = { value: 1 }; // declare a var in window
console.log("handleClick()");
handleClick(); // Logged 1. The 'this' in the method will be window, because the method is called in window


var obj = {
  state: { value: 2 },
  handleClick: function() {
    console.log(this.state.value);
  },
};
console.log("obj.handleClick();");
obj.handleClick(); // Logged 2. The 'this' is referred to obj because the method is called in obj.

// let's reassign the function to a temp var in window
var temp = obj.handleClick;
console.log("temp()");
temp(); // Logged 1. The 'this' in the function is referred to window because the method is called in window.
console.log("window.temp()");
window.temp(); // this is equal to the one above.

console.log("temp.bind(obj)");
temp.bind(obj)(); // Logged 2. Bind the method and call the method, so the 'this' in the function is referred to obj.

console.log("temp.bind(this)");
temp.bind(this)(); // Logged 1. Since this in the executing scope is window. This effectively is the same calling in this.

console.log("temp.bind(window)");
temp.bind(window)(); // Logged 1. This is equal to the one above.

在这里试试:https://codepen.io/anon/pen/OvOpEa?editors=0012

关于此的博文:https://hackernoon.com/understanding-javascript-the-this-keyword-4de325d77f68

回到你的问题

如果您查看您在类中定义的rendercomponentWillMounthandleSomething,就会明白为什么需要将处理程序绑定到this

渲染

// Rerender
ReactCurrentOwner.current = workInProgress;
var nextChildren = void 0;
{
  ReactDebugCurrentFiber.setCurrentPhase('render');
  nextChildren = instance.render();
  if (debugRenderPhaseSideEffects) {
    instance.render();
  }
  ReactDebugCurrentFiber.setCurrentPhase(null);
}

这就是 react 调用 redner() 的方式,其中实例是具有状态、道具等的对象实例。您可以通过在渲染方法中放置断点并返回调用堆栈来非常轻松地尝试它。

handleSomething

例如,如果你这样定义你的类,用handleSomething作为按钮的onClick回调方法。

class Button extends Component {
  handleSomething() {
    // 'this' will be undefined.
  }

  render() {
    return (<button onClick={this.handleSomething}>Test</button>);
  }
}

如果你点击按钮,这就是 react 调用 onClick 处理方法的方式。

  function callCallback() {
    fakeNode.removeEventListener(evtType, callCallback, false);
    // This is where react calls your method.
    func.apply(context, funcArgs);
    didError = false;
  }

在我的调试经验中,funchandleSomethingcontext 通常是 undefinedfuncArgs 是函数中传递的参数。

apply 类似于bind。第一个参数用于指定函数的this,第二个参数是传入函数的参数数组。

有关apply的更多信息,请参见MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

在这种情况下,方法handleSomething 被调用,undefinedthis;因此,如果您没有绑定该方法,您的this 将是undefined

我注意到虽然 handleSomething 必须手动绑定到这个, render 和 componentWillMount 没有。方法是否绑定于此 已经?

它们是使用您的类的实例调用的,因此它们已经将this 作为您的实例,而没有使用bind。我想你可以说它已经绑定到this

为了符号一致性,可以手动绑定吗?

您不需要将 this 与 react 的生命周期方法绑定。如果你真的想,我想你也可以将这些方法绑定到this(可能会有一些我不知道的副作用,因为我并没有真正深入研究它们的源代码),但这是喜欢做obj.handleClick.bind(obj)(); 而不是obj.handleClick();。这是不必要的,并且会花费一些时钟周期做一些不需要的事情。

【讨论】:

    猜你喜欢
    • 2014-06-24
    • 2019-10-19
    • 1970-01-01
    • 2010-11-28
    • 2011-12-18
    • 1970-01-01
    • 2019-08-16
    • 2022-01-16
    • 1970-01-01
    相关资源
    最近更新 更多