reactjs - prop 更改时重新渲染 React 组件

标签 reactjs redux react-redux

我正在尝试将演示组件与容器组件分开。我有一个 SitesTable 和一个 SitesTableContainer。容器负责触发 redux 操作以根据当前用户获取适当的站点。

问题是在容器组件最初渲染之后,当前用户被异步获取。这意味着容器组件不知道它需要重新执行其 componentDidMount 函数中的代码,该函数将更新数据以发送到 SitesTable。我认为当容器组件的 props(用户)之一发生更改时,我需要重新渲染容器组件。我该如何正确地做到这一点?

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))
  }  
}

使用 Hooks(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 .

关于reactjs - prop 更改时重新渲染 React 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37009328/

相关文章:

javascript - 我想在从 firebase-database 获取时间后运行一个计时器,如何在 React JS 中使用 setInterval() 将时间减少一秒

reactjs - react-router-dom:从 <BrowserRouter> 组件中获取 props.location

javascript - 使用 sortBy redux 操作对 redux 存储数组进行排序不会向组件发送新的 props

reactjs - 使用Redux-Form,如何拥有多个同名输入?

javascript - 使用方法渲染 vs 变量有什么优势?

在 docker 容器中构建 react 应用程序时,JavaScript 堆内存不足

promise ,如果发生错误,不要触发 'then'

javascript - 尽管 console.log 显示正确的值,但 Textfield 不会对Reducer使用react

javascript - reducer 中未定义初始变量

javascript - react : array "contains" method