[解決済み] プロップ変更時にReactコンポーネントを再レンダリングする
2022-08-02 06:12:23
質問
コンテナコンポーネントから表示用コンポーネントを分離しようとしています。私は
SitesTable
と
SitesTableContainer
. コンテナは、現在のユーザーに基づいて適切なサイトを取得するためにreduxアクションをトリガーする役割を担っています。
問題は、コンテナコンポーネントが最初にレンダリングされた後に、現在のユーザが非同期にフェッチされることです。つまり、コンテナ コンポーネントは、その
componentDidMount
関数に送信するデータを更新するコードを再実行する必要があることを、コンテナ コンポーネントは知らないということです。
SitesTable
. 私は、コンテナコンポーネントのプロップの1つ(ユーザー)が変更されたときに、コンテナコンポーネントを再レンダリングする必要があると思います。どのように私はこれを正しく行うのですか?
class SitesTableContainer extends React.Component {
static get propTypes() {
return {
sites: React.PropTypes.object,
user: React.PropTypes.object,
isManager: React.PropTypes.boolean
}
}
componentDidMount() {
if (this.props.isManager) {
this.props.dispatch(actions.fetchAllSites())
} else {
const currentUserId = this.props.user.get('id')
this.props.dispatch(actions.fetchUsersSites(currentUserId))
}
}
render() {
return <SitesTable sites={this.props.sites}/>
}
}
function mapStateToProps(state) {
const user = userUtils.getCurrentUser(state)
return {
sites: state.get('sites'),
user,
isManager: userUtils.isManager(user)
}
}
export default connect(mapStateToProps)(SitesTableContainer);
どのように解決するのですか?
の中に条件を追加する必要があります。
componentDidUpdate
メソッドに条件を追加する必要があります。
この例では
fast-deep-equal
を使用してオブジェクトを比較しています。
import equal from 'fast-deep-equal'
...
constructor(){
this.updateUser = this.updateUser.bind(this);
}
componentDidMount() {
this.updateUser();
}
componentDidUpdate(prevProps) {
if(!equal(this.props.user, prevProps.user)) // Check if it's a new user, you can also use some unique property, like the ID (this.props.user.id !== prevProps.user.id)
{
this.updateUser();
}
}
updateUser() {
if (this.props.isManager) {
this.props.dispatch(actions.fetchAllSites())
} else {
const currentUserId = this.props.user.get('id')
this.props.dispatch(actions.fetchUsersSites(currentUserId))
}
}
フックの使用 (React 16.8.0+)
import React, { useEffect } from 'react';
const SitesTableContainer = ({
user,
isManager,
dispatch,
sites,
}) => {
useEffect(() => {
if(isManager) {
dispatch(actions.fetchAllSites())
} else {
const currentUserId = user.get('id')
dispatch(actions.fetchUsersSites(currentUserId))
}
}, [user]);
return (
return <SitesTable sites={sites}/>
)
}
比較するpropがオブジェクトや配列の場合は
useDeepCompareEffect
の代わりに
useEffect
.
関連
-
[解決済み】React 17で動作するEnzymeアダプターはどれですか?
-
[解決済み】Reactコンポーネント内でswitchステートメントを使用するには?
-
[解決済み】ReactJS: マテリアルuiのブレークポイントについて
-
[解決済み] Next.jsでWebSocketを利用する
-
[解決済み] プロップ `history` は `Router` で必須とマークされているが、その値は `undefined` である。
-
[解決済み] Reactプロジェクトに.envファイルを追加する
-
[解決済み] Reactルータを使ったプログラムによるナビゲーション
-
[解決済み] React JSX内のループ
-
[解決済み] setStateを呼び出さずにReactコンポーネントを強制的に再レンダリングすることは可能ですか?
-
[解決済み] mapDispatchToPropsとは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】React 17で動作するEnzymeアダプターはどれですか?
-
[解決済み】コンポーネントの定義に表示名がない react/display-name
-
[解決済み】Reactでclsxを使用する方法
-
[解決済み】React Propsが定義されていません。
-
[解決済み] Apolloクライアントでログアウトした後、ストアをリセットする
-
[解決済み] reactでonloadを使うには?
-
[解決済み] ReactJS giving error Uncaught TypeError: Super expression は null か関数でなければならず、undefined ではありません。
-
[解決済み] MUI Boxは何のためのコンポーネントですか?
-
[解決済み] React Router - バージョン更新後のwithRouterでTypescriptエラーが発生する。
-
[解決済み] Reactプロジェクトに.envファイルを追加する