如何通过现有的带钩子的 redux 操作获取数据?

How to fetch data by existing redux action with hooks?

我正在尝试了解 React Hooks。我想要的是通过使用 useEffect 挂钩调用 redux 操作来获取功能组件内的数据。 我知道我可以将道具传递给状态

 const [todoList] = useState(props.todoList)

但是通过现有的 redux 操作获取数据的最佳实践是什么?

在 React class 组件中,我调用此方法在 componentDidMount() 中获取数据,并且一切正常。

import React, { useEffect } from 'react'
import { connect } from 'react-redux'
import { ITodo } from './types'
import { getTodos } from '../actions/todoActions'

interface IProps {
    todoList: Array<ITodo>

    getTodos: typeof getTodos
}


const Todos = (props: IProps) => {

    useEffect(() => {
          props.getTodos()
    }, [props.todoList])



    return (
         <div>
             {props.todoList.map((_) => (<div key={_.Id}>{_.Name}</div>))}
         </div>
      )
 }

 const mapStateToProps = (state) => ({
     todoList: state.todo.todoList
 })

 const mapDispatchToProps = {
     getTodos
 }


  export default connect(mapStateToProps, mapDispatchToProps)(ProdRoute)

我希望获得带有道具的待办事项列表,并且 props.getTodos() 应该像在 componentDidMount() 方法中那样调用一次。但实际上我得到数据和 getTodos() 被一遍又一遍地调用,但应该在组件 mount

上调用一次

请注意,如果您将 [props.todoList] 传递给 useEffect,您会错误地强制不断刷新,因为:

  • useEffect 进行实例比较 (===) 以了解 props.todoList 是否已更改
  • 在第一次渲染后调用 props.getTodos() 调度程序
  • props.todoList 更新时,将重新呈现组件
  • useEffect 调用将收到 [props.todoList] 作为值以检查是否需要重新 运行 或
  • props.todoList 已更改(它是空的,现在已被增值)并且 props.getTodos() 被重新命名为
  • redux 使用相同的值更新 todoList 但改变了数组引用
  • 重新渲染组件,useEffect 将检查 [props.todoList] 参数是否已更新...但它已被更新,因为之前的 props.todoList 与实际的props.todoList,即使内容相同

所以,如果您只需要调用 props.getTodos() 一次就可以

  • 使用 [props.todoList.length] 而不是 [props.todoList] 作为 useEffect 调用的第二个参数
  • 使用空数组 [] 作为 useEffect 调用的第二个参数(参见 the docs