2

標準の構成関数と 'div' コンポーネントが与えられた場合、次のような 2 つの HOC をどのように記述しますか?

  • 「div」要素は 20 ピクセルの緑色のボックスとして始まり、クリックすると 50 ピクセルの青色のボックスになります。
  • a: 状態を props とマージすること、および b: 状態変更をトリガーすることの懸念は、別々の HOC によって処理されます。
  • updater HOC は状態を props にマップし、デフォルト状態を設定します
  • ディスパッチャ HOC は、クリック時に新しい状態を取得する関数を受け入れます

以下の例は、緑色のボックスを取得するために機能し、ハンドラーを正しく起動します。更新は、Dispatcher HOC の状態でのみ発生します。アップデータ HOC の状態は変更されず、その props も変更されません。

私は何が起こっているのかを理解することに非常に興味があります。Compose で 2 つの HOC の順序を反転すると、ハンドラーが設定されません。それらは両方とも にマージされるため{...this.props}、それは私には意味がありません。複数の HOC が小道具と状態をマージする方法について、私が理解できないことがあると思います。

const HOCDispatcher = myFunc => BaseComponent => {
  return class Dispatcher extends React.Component {
    constructor(props,context){
      super(props,context);
      this.handlerFn = (event)=>{this.setState(myFunc)}
    }
    render(){
      return createElement(BaseComponent,{...this.props,onClick:this.handlerFn});
    }
  }
}

const HOCUpdater = defaultState => BaseComponent => {
  return class Updater extends React.Component {
    constructor(props,context){
      super(props,context);
      this.state = Object.assign({},defaultState,this.state);
    }
    render(){
      return createElement(BaseComponent,{...this.props,...this.state});
    }
  }
}

const MyComponent = compose(
  HOCDispatcher(()=>({
    style:{width:'50px',height:'50px',background:'blue'}
  })),
  HOCUpdater({
    style:{width:'20px',height:'20px',background:'green'}
  }),
)('div');
4

1 に答える 1

1

コードを単純化またはコンパイルして、複雑でない構造にしようとすると、よりよく理解できます。

MyComponent の初期バージョン

const MyComponent= class Dispatcher extends React.Component {
  constructor(props,context){
    super(props,context);
    this.handlerFn = (event)=>{this.setState({
      style:{width:'50px',height:'50px',background:'blue'}
    })}
  }
  render(){
    return <HOCUpdater onClick={this.handlerFn}/>
  }
}

HOCUpdaterまた、次のようにレンダリングされます。

class Updater extends React.Component {
  constructor(props,context){
    super(props,context);
    this.state = {
      style:{width:'20px',height:'20px',background:'green'}
    };
  }
  render(){
    return <div style:{width:'20px',height:'20px',background:'green'}/>;
  }
}

したがって、緑色のボックスをレンダリングします。

クリックをトリガーした後

const MyComponent= class Dispatcher extends React.Component {
  constructor(props,context){
    super(props,context);
    this.handlerFn = (event)=>{this.setState({
      style:{width:'50px',height:'50px',background:'blue'}
    })};
    this.state= {
      style:{width:'50px',height:'50px',background:'blue'}
    };
  }
  render(){
    return <HOCUpdater onClick={this.handlerFn}/>
  }
}

レンダリングに注意を払うと、this.props変更されておらず、まだ空であるため、同じです。Dispatcherしたがって、ボックスの状態は変更されますが、ボックスのスタイルは変更されません。

どこで間違えたかわかりましたか?に変更this.propsするだけthis.stateDispatcher、魔法が起こるのがわかります。

しかし、待ってください。

このようなコード行があるとどうなりますか?

createElement('div',{
  style:{width:'50px',height:'50px',background:'blue'},
  style:{width:'20px',height:'20px',background:'green'}
});

まあ、それはまだ最初のもの(青いボックス)をレンダリングしますが、これを避けるためにレンダリングメソッドをHOCUpdaterこれに変更してみてください:

return createElement(BaseComponent,{...this.state});

componentWillReceivePropsまた、メソッドを追加すると、次のようにHOCUpdaterなります。

const HOCUpdater = defaultState => BaseComponent => {
  return class Updater extends React.Component {
    constructor(props,context){
      super(props,context);
      this.state = Object.assign({},defaultState,this.state);
    }
    componentWillReceiveProps(nextProps){
      this.setState(nextProps);
    }
    render(){
      return createElement(BaseComponent,{...this.state});
    }
  }
}
于 2017-08-28T21:25:24.793 に答える