Javascript 如何在React+;没有新函数创建的Typescript?

Javascript 如何在React+;没有新函数创建的Typescript?,javascript,reactjs,typescript,Javascript,Reactjs,Typescript,假设您拥有以下TSX代码: render() { const someParameter = 5; return ( <div onClick={() => this.doSomething(someParameter)}></div> ); } render(){ 常数someParameter=5; 返回( this.doSomething(someParameter)}> ); } 现在,我们知道我们不应该像这样将

假设您拥有以下TSX代码:

render() {
    const someParameter = 5;

    return (
        <div onClick={() => this.doSomething(someParameter)}></div>
    );
}
render(){
常数someParameter=5;
返回(
this.doSomething(someParameter)}>
);
}
现在,我们知道我们不应该像这样将fat arrow函数传递给onClick处理程序,因为它每次都会创建一个新函数,从而强制重新加载(当我们将回调传递给深层组件而不仅仅是div时,这尤其糟糕)

因此,如果没有参数,那么解决方案是在类的构造函数中将
doSomething
绑定到
this
,比如
this.doSomething=this.doSomething.bind(this)
,然后将绑定函数作为回调传递。然而,在我们的例子中,这并不能解决这个问题,因为我们希望将一个参数传递给函数-someParameter。想象一下,someParameter不仅仅是一个像上面那样愚蠢的常量,而是数组中的一个元素,我们在render方法中的数组上方的map()中得到该元素。我们如何处理这种情况?也就是说,我们如何传递一个不是每次都从头开始创建的函数,从而破坏我们仅在必要时智能地重新加载的能力


谢谢

您能检查一下“Protips”部分中提出的解决方案吗?

看起来这可能有效:

    var List = createReactClass({
              render() {
        return (
          <ul>
            {this.props.items.map(item =>
              <ListItem key={item.id} item={item} onItemClick={this.props.onItemClick} />
            )}
          </ul>
        );
      }
    });

    var ListItem = createReactClass({
      render() {
        return (
          <li onClick={this._onClick}>
            ...
          </li>
        );
      },
      _onClick() {
        this.props.onItemClick(this.props.item.id);
      }
    });
var List=createReactClass({
render(){
返回(
    {this.props.items.map(item=> )}
); } }); var ListItem=createReactClass({ render(){ 返回(
  • ...
  • ); }, _onClick(){ this.props.onItemClick(this.props.item.id); } });
    bind
    不仅允许绑定上下文,还允许绑定参数。因此,您可以在构造函数中执行以下操作:

    this.doSomething = this.doSomething.bind(this, someArgument)
    
    只有当
    someArgument
    在组件生命周期中不发生更改时,上述解决方案才有效。
    如果这个参数是动态的,唯一的解决方案就是像你的例子中那样使用箭头函数——但是请注意,只有当这个函数作为道具传递给子组件(不是HTML元素)时,才可能导致额外的重新渲染。根据react文件:

    在大多数情况下,这很好。但是,如果此回调作为 支撑到较低的组件,这些组件可能会起到额外的作用 重新渲染

    如果不将其传递给React子组件,则不会出现问题,也不会导致任何额外的重新渲染。请注意,React组件和HTML标记之间存在差异。如果使用arrow函数作为HTML元素的事件回调(例如,在map中生成的div上),它将不会触发此
    div
    的额外呈现,因为它不是组件,也没有呈现方法。React虚拟DOM算法将决定是否应该更新与这个
    div
    对应的实际DOM元素,而在我们的例子中,现有的DOM元素将不会更新(您可以使用dev工具进行检查)

    类Hello扩展了React.Component{
    构造函数(){
    超级();
    this.state={test:0};
    }
    componentDidMount(){
    var i=0;
    this.timer=setInterval(()=>{
    i++;
    this.setState({test:i})
    }, 1000)
    }
    组件将卸载(){
    clearInterval(这个.timer)
    }
    render(){
    返回({this.state.test}
    {
    [1,4,6]。地图((v)=>{
    返回({console.log(this.state.test)}>test)
    })
    }
    );
    }
    };
    ReactDOM.render(
    ,
    document.getElementById('容器')
    );
    
    
    
    是,但在构造函数中只调用一次绑定,而不是每次重新渲染时调用。正如我提到的,
    bind
    应该用在constructorAh中,我明白了,这是一个很好的观点。在这种情况下,我仍然希望
    this.doSomething=something=>{…}的可读性,但我认为这是有启发性的。绑定可能更可读,具体取决于您的background@MichaelTontchev我想你误解我了。您不需要将其包装在自己的组件中。这只是一个示例,演示如何将回调传递给已经存在的子组件,以避免触发该子组件的额外重新呈现。如果您想将事件回调添加到HTML元素(而不是React组件),可以使用
    bind
    或arrow函数,它不应该导致任何问题,也不必将其包装到组件中。在HTML元素上使用箭头函数作为道具不会导致任何额外的重新渲染-只有当您将其传递给子元素时才可能出现问题component@Michael如果要将事件回调传递给
    div
    (以便HTML元素不响应组件),请单击在
    map
    中,您可以使用arrow函数,因为正如我提到的,它不会导致这些div的额外重新渲染。当新函数作为prop传递时,只能重新呈现React组件(
    div
    不是React组件)。此外,在每个父组件渲染上创建新的箭头函数不应导致任何性能问题。总之,您可以将arrow函数传递给map中生成的div,如果将其传递给React组件,则应该避免使用它。@michaeltonchev是否使用开发工具检查了我的代码段?开发工具会突出显示每个已更新的DOM元素,但正如您所看到的,代码段中的“div”元素不会被更新,尽管它们每秒都会收到作为事件回调的新函数。这多亏了虚拟DOM优化——DOM元素只有在“可见”更改时才会更新。更改事件回调不需要更新DOM树,因为它不会在DOM中进行可视更改。当然,在“后台”中添加了新的事件处理程序,但它可以在不重新呈现实际DOM元素的情况下完成。我们确实应该先对应用程序进行基准测试,然后再确定不应该传递胖箭头函数