2017-02-27 21 views
2

リアクション内のステートフルコンポーネントを更新する場合、コンポーネントが現在の状態を使用して新しい状態を更新すると、悪い習慣とみなされます。現在の状態に基づいてリアクション内のsetState

たとえば、フィルタが開いているかどうかを保存するクラスがある場合、パフォーマンスの観点から、より状態を更新するためのこれらのオプションの1つはありますか?

オプション1:

class Container extends Component { 
    state = { 
     show: false 
    } 

    show =() => this.setState({ show: true }) 

    hide =() => this.setState({ show: false }) 

    render() { 
     <ExternalComponent 
      show={this.show} 
      hide={this.hide} 
     /> 
    } 
} 

オプション2:

class Container extends Component { 
    state = { 
     show: false 
    } 

    toggleVisibility =() => this.setState({ show: !this.state.show }) 

    render() { 
     <ExternalComponent 
      toggleVisibility={this.toggleVisibility} 
     /> 
    } 
} 

はオプション3:

class Container extends Component { 
    state = { 
     show: false 
    } 

    setShow = (newVal) => this.setState({ show: newVal }) 

    render() { 
     <ExternalComponent 
      setShow={this.setShow} 
     /> 
    } 
} 
+4

私はなぜそれが状態の変更以外の悪い習慣とみなされるのか分かりませんが、非同期でマージ可能です。これはおそらく合理的な懸念です - あなたが期待するものを得ることができないかもしれません。個人的に私はオプション3を好むだろう。 –

答えて

3

自身の状態にアクセスするコンポーネントは何も問題はありません。書き込み専用の状態はあまり役に立ちません。ただし、コンポーネント状態または状態変更メソッドを他のコンポーネントに公開するときは、非常に注意する必要があります。コンポーネントの状態は内部的なものであり、よく考慮されたインタフェースを介して外部からのみ触れて、コンポーネントが絡み合ってしまうのを防ぎます。実際に

は、あなたの例#2 in the React documentationに似ている例があります:

class Toggle extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = {isToggleOn: true}; 

    // This binding is necessary to make `this` work in the callback 
    this.handleClick = this.handleClick.bind(this); 
    } 

    handleClick() { 
    this.setState(prevState => ({ 
     isToggleOn: !prevState.isToggleOn 
    })); 
    } 

    render() { 
    return (
     <button onClick={this.handleClick}> 
     {this.state.isToggleOn ? 'ON' : 'OFF'} 
     </button> 
    ); 
    } 
} 

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

しかし、あなたの例から違いに注意してください。 thisが意味することを意味することを確実にするために、コンストラクタでトグルメソッドをバインドする必要があります。

子コンポーネントの可視性を追跡するコンポーネントがラッピングコンポーネントである場合、トグルメソッドを子コンポーネントに渡すのではなく、ラッパーがある種のhide/showアフォーダンスをレンダリングすることが期待されます。現在の可視性を小道具として子要素に渡すか、選択的にレンダリングするか(選択的レンダリングでは、再度有効にすると子コンポーネント全体が再マウントされるため、高価になる可能性があります。それを作り直して)。ラッパーは可視性を知っており、子コンポーネントはその決定の方法や理由を知る必要はなく、ラッパーの内部状態にも触れる必要はありません。

1

新しい状態値を決定するために現在の状態値を使用することには何も問題ありません。

オプション2は、私には魅力的ではありません。ただし、サードパーティ製のコンポーネント(セマンティックUIリアクションモーダルなど)を使用する場合はオプション1を使用する必要があり、定義する必要があるハンドラを表示および非表示にすることがあります。

オプション3も問題ありません。私はこのshow/hide以外のアプリケーション(実際には、特に入力コンポーネントを制御している場合など)に使用します。

関連する問題