簡體   English   中英

“這個”反應更高階的成分

[英]“this” in react higher order component

我想將反應組件的共享功能移動到更高階的組件,如下所示:

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}
                 />
            );
        }
    }

使用這種語法需要在HOC的構造函數中明確地綁定this

this.deleteItem = this.deleteItem.bind(this);

..但我想綁定包裝的組件。 所以我在包裝組件的構造函數中嘗試的是

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

但這只會導致“無法分配給只讀屬性”錯誤,因為反應道具只是為了讀取。

我知道我可以將狀態項存儲在HOC中並將其作為道具傳遞下去。 但是,其他包裝的組件功能將無法訪問(可寫),對吧? 我想知道是否有一種方法可以共享未綁定的函數,然后將其綁定到包裝的實例。

[編輯]我將Abdul Rauf的回答標記為“已接受”,但我想說Karen Grigoryan的回答是我實際使用的解決方案,因為它的工作原理似乎只適合我的應用程序的復雜性。

我知道我可以將狀態項存儲在HOC中並將其作為道具傳遞下去。 但是,其他包裝的組件功能將無法訪問(可寫),對吧?

您應該在HOC中存儲共享狀態。 您可以將多個狀態更新方法傳遞給它們可以在內部調用的Wrapped組件,以間接更新狀態。

如果您不想傳遞多個狀態更新方法,那么我們有兩個選項:

選項1:在HOC中創建單個dispatch方法,該方法采取action和可選的payload並將其傳遞給Wrapped組件。

// 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:如果您可以使用最新的鈎子支持反應,請使用useReducer鈎子

我想知道是否有一種方法可以共享未綁定的函數,然后將其綁定到包裝的實例。

從技術上講,你可以做到這一點( 檢查Karen Grigoryan的答案 )。 但由於種種原因,這被認為是一種不好的做法。 其中很少是:

  1. 它反對封裝原則。 (State位於Child組件中,狀態更新邏輯位於父組件中)。 父組件不應該知道子組件的狀態。

  2. 道具可以隨時間變化,但這不會自動反映在派生的Instance properties/fields

props只能通過設計閱讀。

React元素是不可變的。 創建元素后,您無法更改其子元素或屬性。 元素就像電影中的單個幀:它代表特定時間點的UI。

從技術上講,將deleteItem綁定到WrappedComponent上下文的方法之一就是在WrappedComponent constructor bind它:

codesandbox示例

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM