2017-02-10 2 views
0

短い話ですが、Reactに、既存の要素を再利用するのではなく、まったく新しい要素を作成したいと思います。これはコンストラクタを再度実行するためです。Reactが強制的に要素を破壊して再構成するような、ハックのない方法はありますか?

デフォルトでは、Reactはできるだけ再利用を試みます。ハックのある回避策は、要素にkeyプロパティを追加することです。たとえば、次のように

class Foo extends React.Component { 
    constructor() { 
    super(); 

    this.state = { 
     forceReloadCounter: 0, 
    }; 
    } 

    _forceReload() { 
    this.setState({forceReloadCounter: this.state.forceReloadCounter + 1}); 
    } 

    render() { 
    return (
     <ChildElement key={this.state.forceReloadCounter}/> 
    ); 
    } 
} 

_forceReloadもし実行すると、それはChildElementkeyを変更するので、リアクトChildElementの古いインスタンスを破棄して新しいものを構築します。しかし、このソリューションは明らかに非常にハッキリです。誰かがコードを読んでいると混乱するでしょう。より良い解決策はありますか?

+0

要素を破棄して再構成する理由は何ですか? – Pineda

+0

わかりませんが、単にDOMから削除するだけで問題はありませんか?ある条件が真である場合にのみそれをレンダリングする条件のように。 'render(){戻り条件? :null} ' –

+0

' componentWillMount'は 'props'以外のソースからデータを取得します。すべてのデータをリセットしてデータを再フェッチするのは混乱します(要素が再利用された場合)。私は要素を再構築し、 'componentWillMount'をもう一度呼び出す方がクリーンであると思います。 –

答えて

1

私はよりクリーンな方法で私のハックな解決策を使用するクラスを書いた。

class RecreateChildOnPropsChange extends React.Component { 
    constructor() { 
    super(); 

    this._forceRecreateCounter = 0; 
    } 

    shouldComponentUpdate(nextProps) { 
    assert(nextProps.children, 'Every props object should have childrens.'); 

    let props = this.props; 
    if (props === nextProps) { 
     return true; 
    } 

    let keys = Object.keys(props); 
    let nextKeys = Object.keys(nextProps); 

    if (keys.length !== nextKeys.length) { 
     return false; 
    } 

    for (let key of keys) { 
     if (key !== 'children' && (!nextProps.hasOwnProperty(key) || props[key] !== nextProps[key])) { 
     return true; 
     } 
    } 

    return false; 
    } 

    render() { 
    this._forceRecreateCounter++; 

    return React.cloneElement(
     React.Children.only(this.props.children), 
     {key: this._forceRecreateCounter} 
    ); 
    } 
} 

それはこのように使用されるでしょう:RecreateChildOnPropsChange変更のいずれかのプロパティが、それはその子要素を破棄し、再作成した場合

<RecreateChildOnPropsChange startingPage={page}> 
    <Newsfeed startingPage={page}/> 
</RecreateChildOnPropsChange> 

関連する問題