プレゼンテーション コンポーネントをコンテナー コンポーネントから分離しようとしています。 と があります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);
ベストアンサー1
メソッドに条件を追加する必要があります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}/>
)
}
比較するプロパティがオブジェクトまたは配列の場合は、useDeepCompareEffect
の代わりにuseEffect
。