Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript &引用;这";高阶组分中的反应_Javascript_Reactjs - Fatal编程技术网

Javascript &引用;这";高阶组分中的反应

Javascript &引用;这";高阶组分中的反应,javascript,reactjs,Javascript,Reactjs,我想将共享功能从react组件移动到更高阶的组件,如下所示: function withListFunctions(WrappedComponent) { return class extends React.Component { constructor(props) { super(props); } // my shared functionality deleteItem() {

我想将共享功能从react组件移动到更高阶的组件,如下所示:

function withListFunctions(WrappedComponent) {
    return class extends React.Component {
        constructor(props) {
            super(props);
        }
        // my shared functionality
        deleteItem() {
            // Do something, then ...
            this.setState({itemDeleted: true});
        }
        render() {
            return (
                <WrappedComponent
                    deleteItem={this.deleteItem}
                 />
            );
        }
    }
。。但是我想绑定包装好的组件。所以我在包装组件的构造函数中尝试的是

this.props.deleteItem = this.props.deleteItem.bind(this);
但这只是导致了一个“无法分配到只读属性”错误,因为react道具是只读的


我知道我可以将状态项存储在HOC中,并将其作为道具传递下去。但它将不再被其他包装组件函数访问(可写),对吗?我想知道是否有一种方法可以共享未绑定的函数,然后将其绑定到已包装的实例

[编辑]我将Abdul Rauf的答案标记为“已接受”,不过我想声明Karen Grigoryan的答案是我实际使用的解决方案,因为它很有效,而且似乎正好适合我的应用程序的复杂性

我知道我可以将状态项存储在HOC中并传递它
作为道具放下。但它将不再可访问(可写) 通过其他包装组件函数,对吗

您应该将共享状态存储在HOC中。您可以将多个状态更新方法传递给包装好的组件,这些组件可以在内部调用以间接更新状态

如果您不想传递多个状态更新方法,则我们有2个选项:

选项1:在HOC中创建一个
分派
方法,该方法执行
操作
和可选的
有效负载
,并将其传递给包装组件

// Do not mutate state in reducer. always return a new state
reducer(state, action) {
  switch (action.type) {
    case 'delete':
      // return final state after delete
    case 'add':
      // return final state after add using action.payload
    case 'update':
      // return final state after update using action.payload
    default:
      // A reducer must always return a valid state.
      // Alternatively you can throw an error if an invalid action is dispatched.
      return state;
  }
}


dispatch(action) {
    const updatedState = this.reducer(this.state, action)
    this.setState(updatedState);
}
选项2:如果可以使用最新的react with hooks支持,请使用

我想知道是否有一种方法可以共享未绑定函数,然后 将其绑定到包装的实例

从技术上讲,您可以这样做()。但由于许多原因,这被认为是一种不好的做法。其中很少有:

  • 它违反了封装原则。(状态在子组件中,状态更新逻辑在父组件中)。父组件不应该知道关于子组件状态的任何信息

  • 道具可以随时间变化,但这不会自动反映在派生的
    实例属性/字段中


  • 道具是只读的

    React元素是不可变的。创建元素后,不能更改其子元素或属性。元素就像电影中的单个帧:它表示某个时间点的UI

    因此,从技术上讲,将
    deleteItem
    绑定到
    WrappedComponent
    上下文的方法之一就是在
    WrappedComponent
    构造函数中绑定它:


    this.deleteItem=this.props.deleteItem.bind(this)

    注意:确定这是否有效,但您尝试过吗
    this.deleteItem=this.deleteItem.bind(WrappedComponent)
    @PatrickHund您的解决方案绑定到类而不是实例您是对的,这不起作用虽然React更喜欢组合而不是继承,但如果有意义,您仍然可以使用继承。如果您想创建一个没有继承的包装组件,我会将要包装的组件作为一个道具传递。“但是它将不再被其他包装组件函数访问(可写),对吗?”不,如果您像
    setDeletedItem={this.setDeletedItem}这样传递道具,它将是可写的
    转化为
    你能用几句话具体说明为什么Karen Grigoryan的回答被认为是一种不好的做法吗?它是否有具体的缺点,或者只是没有按照框架的观点来组织事情?
    
    // Do not mutate state in reducer. always return a new state
    reducer(state, action) {
      switch (action.type) {
        case 'delete':
          // return final state after delete
        case 'add':
          // return final state after add using action.payload
        case 'update':
          // return final state after update using action.payload
        default:
          // A reducer must always return a valid state.
          // Alternatively you can throw an error if an invalid action is dispatched.
          return state;
      }
    }
    
    
    dispatch(action) {
        const updatedState = this.reducer(this.state, action)
        this.setState(updatedState);
    }