React高阶组件

class Demo extends React.Component{
    render(){
      let data = [
        {
          name: '科目一',
        id: '1'
      },
      {
          name: '科目二',
        id: '2'
      },
      {
          name: '科目三',
        id: '3'
      }
    ];
      return (
        <MyComponent data={data} fieldName={{label: 'name', key: 'id'}}/>
    );
  }
}

const showAlert = function(){
        let str = '';
        for(var i = 0; i < arguments.length; i++){
        str += JSON.stringify(arguments[i]) + '\n';
    }
     alert(str);
};

//HOC 高阶组件的应用
let withRenameFieldName = (WrappedComponent) => {
    return class extends React.Component{
      render(){
        let { data, fieldName, ...props } = this.props;
      let tmpData = data.slice();
      if(fieldName){
        tmpData.map(item => {
          for(let rename in fieldName){
              if(item[fieldName[rename]]){
                item[rename] = item[fieldName[rename]];
                delete item[fieldName[rename]];
              }
            }
        });
      }
        showAlert(tmpData, data);
        return <WrappedComponent {...props} data={tmpData} defaultData={data}/>
    }
  }
};

class MyComponent extends React.Component{
    render(){
      let { data, defaultData } = this.props;
    
    return (
        <ul>
          {data.map((item, index) => (
            <li key={item.key}>
              {item.label}
            </li>
        ))}
        </ul>
    );
  }
}

MyComponent = withRenameFieldName(MyComponent);

ReactDOM.render(
    <Demo/>,
  document.getElementById('root')
);

因为MyComponent有一个data属性,我想让这个data的属性名称是可配的,所以写了一个withRenameFieldName高阶组件,赋予组件一个新的data属性(更新属性名后的)和defaultData属性(原始data),但是不知道为什么defaultData的属性也被改了,这个应该怎么写才好呢?

阅读 2.1k
2 个回答

clipboard.png
slice这种方式来获取一个新数组,但是slice使用的是浅引用的方式,所以data和tmpData中的对象是同一个,而你之后的操作又都是在对象上,所以data和tmpData的表现一致

因为在你定义的高阶组件中,你的data与defaultData其实数据来源都是一样的。

因为高阶组件会多一层闭包,因此在普通情况下不要轻易使用。这会增加函数调用栈的层数而导致代码性能降低。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题