我正在尝试将表示性组件与容器组件分开。我有一个SitesTable和一个SitesTableContainer。容器负责触发redux操作,以根据当前用户获取适当的网站。
SitesTable
SitesTableContainer
问题是在最初呈现容器组件之后,异步获取了当前用户。这意味着容器组件不知道它需要重新执行其componentDidMount函数中的代码,该代码将更新数据以发送到SitesTable。我认为我需要在其props(user)之一更改时重新渲染容器组件。如何正确执行此操作?
componentDidMount
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方法中添加条件。
componentDidUpdate
该示例fast-deep-equal用于比较对象。
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。
useDeepCompareEffect
useEffect