React Hooks和React-Redux connect:使它们协同工作的最佳实践是什么?

时间:2019-07-30 09:43:37

标签: reactjs redux react-redux react-hooks

我想向社区询问,使用React-redux connect()和依赖管理(如useEffect()这样的钩子)结合现有代码的最佳实践是什么。

让我们看下面的示例:

/* ... */

const mapStateToProps = (state) => ({
  todos: getTodos(state),
  currentUserId: getCurrentUserId(state)
})

const mapDispatchToProps = (dispatch) => ({dispatch})

const mapMergeProps = (stateProps, {dispatch}, ownProps) => {
  return {
    ...stateProps,
    ...dispatchProps,
    ...ownProps,
    fetchTodos: () => dispatch(fetchTodos(stateProps.currentUserId))
  }
}

const TodosListContainer = connect(mapStateToProps, mapDispatchToProps, mapMergeProps)

const TodosList = ({todos, fetchTodos, ...props}) => {

  const _fetchTodos = useCallback(fetchTodos, [])

  useEffect(() => {
    _fetchTodos()
  }, [_fetchTodos])

  return (
    <ul>
      {todos && todos.map((todo) => <li key={todo.id}>{todo.name}</li>)}
    </ul>
  )
}

在上面的代码中,useEffect具有所有依赖性,并且useCallback确保useEffect仅被触发一次。

但是,这似乎是一个额外的样板:如果不使用useCallback,则每次状态更改时都会重新创建从connect的mapMergeToProps传递过来的作为props传递的函数,并触发useEffect

我的问题是上面的代码是否正确,并且在描述的上下文中有更好的方法来处理useEffect。

1 个答案:

答案 0 :(得分:2)

我将其更改为以下

// Leave this one like it is
const mapStateToProps = (state) => ({
  todos: getTodos(state),
  currentUserId: getCurrentUserId(state)
})

// Map the fetchTodos here
const mapDispatchToProps = {
  fetchTodos,
}

// Completely remove the mergeProps
const TodosListContainer = connect(mapStateToProps, mapDispatchToProps)

// Then use the hook like this
const TodosList = ({ todos, fetchTodos, currentUserId, ...props }) => {

  useEffect(() => {
    fetchTodos(currentUserId)
  }, [fetchTodos, currentUserId])

  return (
    <ul>
      {todos && todos.map((todo) => <li key={todo.id}>{todo.name}</li>)}
    </ul>
  )
}

这不会在每次渲染时触发useEffect,因为道具保持不变。它删除(部分)样板代码。我还认为,这样可以更轻松地了解正在发生的事情,并且在currentUserId发生变化(这可能是要发生的情况)时,它将起到效果。