我想向社区询问,使用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。
答案 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
发生变化(这可能是要发生的情况)时,它将起到效果。