2017-08-11 8 views
0

は、私はこれがあります。React JSX:親コンポーネントの再レンダリングが子コンポーネントを再マウントするのは正常ですか?私のアプリに反応のルートコンポーネントで

class App extends Component { 
... 
    ComponentDidMount() { 
    window.addEventListener('resize', this.handleResize, false); 
    } 
    handleResize{ 
    this.parentSize = {height: window.innerWidht - this.node.offsetLeft ..., width: ...}; 
    this.forceUpdate(); 
    } 
    render() { 
    <div ref="e=>this.node=e}> 
     <ChildComponent parentSize={this.ParentSize} /> 
    </div> 
    } 
} 

を、そうcomponentWillUnmount(I)は、どちらかSETSTATEまたはforceUpdate(を通じて、アプリケーション・コンポーネントの再描画時に気づい、子コンポーネントは、実際に再マウントされますcomponentWillMount、componentDidMountは更新ごとに呼び出されます)。私が期待している動作は、子コンポーネントのレンダー機能だけが再び呼び出されるということです。私は最近、React-router 4.xにアップグレードしたので、これに関連するかどうかはわかりません。

これは設計上のものかどうかわかりますか?私のcomponentDidMountを複数回呼び出すと、データをフェッチしようとするときにいくつかの問題が発生し、リサイズ中にその高価な操作を何度もやりたくないのです。

UPDATE:

私は、この問題の可能性の高い原因を発見しました。複数のコンポーネントがネストされていますが、プロジェクト全体を投稿するのは難しいので、問題の原因となっている実際のコードを投稿することが難しい場合があります。しかし、私はこれがそれだと思う:

ここ
return (
    <div className="app-view" style={style} ref={el=>this.node=el}> 
    <Switch> 
     <Route exact path='/' component={() => <Home store={store} />} /> 
     <Route path='*' component={Error404} /> 
    </Switch> 
    </div> 
); 

私はルート内のコンポーネントに小道具を渡すためにしようとしています(リアクト-ルータ4.xを) 私はホーム・ページを作成する機能を提供することにより、これを行う、どのおそらくすべてのレンダリングでホームページを再作成しています。

ですから、ルート内のすべてのレンダリングでページの再作成なしで小道具を渡すにはどうすればよいですか?

+1

ChildComponentコードを追加できますか?ナビゲートしない限り、componentDidMountを何度も呼び出さないでください。 – Dev

+0

おそらく、子は、再レンダリングをスローする更新された小道具または状態のセットを受け取っています。子コンポーネントを共有してください。 –

+0

更新された参照:()=>ルート内のは私が思う問題を引き起こしています。 子コンポーネントコードは、問題をデバッグするためにライフサイクルメソッドをコンソールに記録するだけのダミーに置き換えられました。だから問題は親コンポーネントにあり、私はそれが私の質問の更新されたセクションにあると信じています。 –

答えて

2

最近のReact-Router 4.xのアップグレードに関する問題を確認しました。 React-Routerのドキュメント:

ルーターは、以下のrenderまたはchildrenの代わりにcomponentを使用すると、React.createElementを使用して、指定されたコンポーネントから新しいReact要素を作成します。つまり、コンポーネント属性にインライン関数を指定すると、レンダリングごとに新しいコンポーネントが作成されます。これにより、既存のコンポーネントをアンマウントし、新しいコンポーネントをマウントするだけで既存のコンポーネントを更新するのではなくなります。インライン・レンダリングにインライン関数を使用する場合は、renderまたはchildrenのprop(下)を使用します。

皆様のご支援ありがとうございます。

0

あなたが投稿したコードから私には、あなたが言及した機能の両方がthis.parentSizeに変更されてからページを再レンダリングするように思えます。 this.parentSizeの値が変更されない場合は、イベント、その値が再割り当てされている:

this.parentSize = {height: window.innerWidht - this.node.offsetLeft ..., width: ...}; 

私の理解が正しければ、コンポーネントを生成するために使用される情報を持っているので、それは、再レンダリングする子コンポーネントのために必要です変更されたため、小道具の変更を考慮してコンポーネントを再レンダリングする必要があります。 DOMに変更がない場合もありますので、ページは視覚的に変化しません。

Perfアドオンを使用し、printOperations機能を使用して、実行されている操作を確認できます。

レンダリング再を防止するための一つの方法は、あなたがコンポーネントを再

EDITレンダリングしたくないときshouldcomponentupdateを使用してfalseを返すために、次のようになります上記の情報に基づいて

を、それはあなたがしたいようです親コンポーネントの関数を呼び出して子コンポーネントを更新するが、親を再レンダリングしないようにするには?

このような場合は、次の手順を実行して、これを行うことができます:あなたはcomponentWillMountを呼び出し、

子コンポーネントをレンダリングする最初の時間を、あなたは親から制御できるようにしたい小道具を取得し、このV、その時から

updateMyProp(newProp) { 
    this.setState({ 
    myProp: newProp 
    }) 
} 

componentWillMount() { 
    const { myProp } = this.props; 
    this.setState({ 
    myProp 
    }); 
} 

は、このコンポーネントでは、関数のようなものと呼ばれます。このように、状態として保存します親ページからあなたがupdateMyProp関数を呼び出すことができ、今

<Yourcomponent 
    ref={d=> this.componentName = d} 
    ... 
/> 

:ariableがstateなくprops

次によって制御され、親ページで、コンポーネントは、このようなref変数を、持っている必要があります次の手順を実行して:

this.componentName.updateMyProp(someNewValue) 

これは親

子コンポーネントがrenrederせしませんが、

私はあなたの質問を正しく理解してくれることを願っています!

+0

更新された参照:()=>のルート内に問題が発生していると思います。 –

+0

@Feyziの回答が更新されました – Alex

関連する問題