如您所知,React会自动将所有事件委托给文档,就像这里的大列表一样:
handleTodo(){}
render() { todos.map((todo)=><li onClick={this.handleTodo}>{todo.name}</li>)}
会生成待办事项列表,但onClick事件将委托给文档,对吧?
但问题是关于绑定功能。
handleTodo(todo){/**update todo */}
render(){todos.map((todo)=><li onClick={this.handleTodo.bind(this,todo)}>{todo.name}</li>)}
对于每个待办事项,由于参数不同,因此存在不同的绑定功能。什么时候生成这些功能? React是否也将这些功能委托给文档?如果一个巨大的列表,有数千个绑定功能会导致性能问题吗?
答案 0 :(得分:3)
何时生成这些功能?
这听起来有点滑稽,但是:当你的render
函数被调用时。每次调用render
时,都会为每个函数创建一个新的绑定函数。
(当事件真正发生时,React也会做一些绑定。)
React是否也将这些函数委托给文档?
更准确地说,React在文档级别使用单击处理程序,然后调度事件本身。它没有在文档上注册一堆点击处理程序,每个onClick
都有一个点击处理程序。
如果一个巨大的列表,有数千个绑定功能会导致性能问题吗?
那种&#34;一根绳子有多长?&#34;问题,但请注意the React events documentation:
我们通常建议在构造函数中使用绑定或使用属性初始化程序语法来避免这种性能问题。
当然,如果你绑定每个待办事项,你就不能在构造函数中做到这一点。也许你想在创建待办事项时做一次并让todo携带它的处理程序。
为了找出绑定发生的时间,我们可以使用我们自己的函数包装Function.prototype.bind
并看到它发生:
// Wrap `bind` so we can see when it's used
if (function foo() {}.name !== "foo") {
console.log("Note: Your browser's JavaScript engine doesn't support the Function#name property");
}
const bind = Function.prototype.bind;
Function.prototype.bind = function(...args) {
const name = this.name || "(no name)";
console.log(`Binding "${name}"`);
return bind.apply(this, args);
};
class Example extends React.Component {
constructor(...args) {
super(...args);
this.state = {items: [1, 2, 3, 4]};
}
handler(n) {
console.log("Clicked, n = " + n);
}
render() {
console.log("Entering render");
const result =
<div>
{this.state.items.map(n => <div key={n} onClick={this.handler.bind(this, n)}>Click me</div>)}
</div>
;
console.log("Leaving render");
return result;
}
}
ReactDOM.render(
<Example />,
document.getElementById("react")
);
&#13;
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
&#13;