【问题标题】:Why is useEffect hook not calling functions in first render?为什么 useEffect 钩子在第一次渲染时不调用函数?
【发布时间】:2021-11-22 14:14:04
【问题描述】:

readTodos() 是一个 redux 动作创建者,它从 localstorage 获取 Todo 项并将它们存储在 redux 状态 (globalstate)。我想在useEffect 函数中调用readTodos() 函数并更新globalstate 变量,该变量将在第一次渲染中显示ViewTodos 组件中的所有TodoItems。但是,当组件加载并且返回函数中的列表没有被填充时,readTodos() 操作不会被调用。

import Container from 'react-bootstrap/Container';
import {  useEffect, useState } from "react";
import { useDispatch,useSelector } from "react-redux";
import { bindActionCreators } from "redux";
import { actionCreators,State } from "../../state/state";
import { TodoInterface } from "./interfaces";
import {  Row } from 'react-bootstrap';
import "../styles/createTodoStyles.css"

export const ViewTodos =():JSX.Element =>{
   //REDUX starts here
  const dispatch = useDispatch();
  const {readTodos} =bindActionCreators(actionCreators,dispatch);
  const globalstate = useSelector((state:State) => state.todo)

   useEffect(()=>{
    readTodos();
   },[]);
    
    return(
        <Container>
          <Row>
              <h1>Todo List</h1><ul>
        {
          globalstate.Inprogress.map(Element =>{
            return (
              <li> {Element.Title} </li>
            )
          })
        }
        </ul>
          </Row>
          
        </Container>
    )
}

readTodos()动作创建者代码:

export const readTodos = () =>{

    var mystorage = window.localStorage;
    var Completed = JSON.parse(mystorage.getItem("completed")|| "[]");
    var Inprogress = JSON.parse(mystorage.getItem("inprogress")|| "[]");

    var todolist={
        Completed:Completed,
        Inprogress:Inprogress
    }

    return (dispatch:Dispatch) =>{
        dispatch({
            type:"readTodo",
            payload:todolist
        })
    }
}

【问题讨论】:

  • 您是否通过在函数中放置console.log() 来验证readTodos() 实际上没有被调用?在 react 生命周期中,useEffect 在组件挂载后被调用。
  • 我刚刚尝试过,它在第一次渲染时被调用。我的 redux 状态变量(globalstate)也在更新,但是我的 Todos 列表没有更新。

标签: reactjs typescript react-redux react-hooks use-effect


【解决方案1】:

您的 redux 操作是异步的,因此即使它在初始渲染时启动,该数据在渲染结束时还没有加载到 redux 存储中。我建议在尝试映射之前检查以确保 globalState.Inprogress 存在(或长度大于零,具体取决于您的用例)。

return (
  <Container>
    <Row>
      <h1>Todo List</h1>
      <ul>
        {globalstate.Inprogress && // or globalstate.Inprogress.length > 0 &&
          globalstate.Inprogress.map(Element =>{
            return (
              <li> {Element.Title} </li>
            )
          })
        }
      </ul>
    </Row>
  </Container>
)

【讨论】:

  • 本地存储上的操作本质上是异步的还是 redux 调度本身是异步的?我已经更新了描述中的代码。我尝试检查 globalState.Inprogress 是否存在,但它对我不起作用。
猜你喜欢
  • 2022-01-20
  • 2021-01-06
  • 2021-09-03
  • 2022-09-23
  • 2021-02-27
  • 2020-02-28
  • 1970-01-01
  • 2019-10-17
  • 2020-01-11
相关资源
最近更新 更多