【问题标题】:React useState not updating state反应useState不更新状态
【发布时间】:2021-01-14 20:53:19
【问题描述】:

我正在使用电影应用程序训练 React Hooks,但现在遇到了一个问题。当我单击Header 组件中的按钮时,应该会通过清理itemsList 数组来改变状态。该代码实际上是为 Load More 按钮准备的,当 API 请求与其他组件(尚不存在)一起使用时,它将向该数组添加更多项目。 问题是数组没有被清理,当一些按钮是陈词滥调时,来自 que API Request 的项目被添加到它。

这是 App.js 文件

import React, { useState } from "react";
import axios from "axios";
import Header from "./Containers/Header";

export default function App() {
  const [values, setValues] = useState({
    msdb: "API_CODE",
    page: 1,
    totalPages: 0,
    listType: "popular",
    mode: "movie",
    itemsList: [],
    searchFiled: "",
    loading: false,
    error: false
  });
  const { msdb, page, totalPages, listType, mode, itemsList, searchFiled, loading, error } = values;

  const modeSelection = (event) => {
    let modeType = "";
    let selectedMode = event.target.innerText;
    console.log(selectedMode);
    if (selectedMode === "Movies") {
      modeType = "movie";
    } else if (selectedMode === "Series") {
      modeType = "tv";
    }
    setValues((prevValues) => {
      return { ...prevValues, mode: modeType, itemsList: [] };
    });
    let endPoint = `https://api.themoviedb.org/3/${mode}/${listType}?api_key=${msdb}&page=${page}`;
    fetchItems(endPoint);
  };

  const fetchItems = (endPoint) => {
    axios
      .get(endPoint)
      .then((response) => {
        const newItemsList = [...itemsList];
        const newItems = response.data.results;
        if (newItems) {
          setValues((prevValues) => {
            return {
              ...prevValues,
              page: response.data.page,
              itemsList: [...newItemsList, ...newItems],
              loading: false,
              totalPages: response.data.total_pages
            };
          });
        }
      })
      .catch((error) => {
        setValues({ ...values, error: true });
        console.log(error);
      });
  };

  return (
    <div className="App">
      <Header mode={modeSelection} />
    </div>
  );
}

这是 Header.js 文件

import React from "react";
import "./Header.css";
import { NavLink } from "react-router-dom";

export default function Header(props) {
  return (
    <div>
      
        <div className="top-center">
          <NavLink to="/movies" onClick={props.mode} className="ch-button">
            Movies
          </NavLink>
          <NavLink to="/series" onClick={props.mode} className="ch-button">
            Series
          </NavLink>
        </div>
        
    </div>
  );
}

所以我想要的结果是,当单击 Header 组件按钮时,应该清理 itemsList 数组,并且 API 请求将再次填充它。请记住,axios 方法已经为另一个组件中的加载更多按钮做好了准备,在这种情况下,它将向数组中添加更多项目。某处应该有一个useEffect吗? 谢谢

【问题讨论】:

    标签: reactjs react-hooks use-state


    【解决方案1】:

    问题在于 setState 的异步特性。您正确使用 prevState 设置新项目,但是在设置新项目时的“fetchItems”中,您从当前状态而不是 prevState 获取旧项目。这样,当您使用它来设置新项目时,状态尚未使用空数组更新。你可以试试

            if (newItems) {
              setValues((prevValues) => {
                return {
                  ...prevValues,
                  page: response.data.page,
                  itemsList: [...prevState.itemsList, ...newItems],
                  loading: false,
                  totalPages: response.data.total_pages
                };
              });
            }
    

    【讨论】:

    • 成功了!为什么添加 const modeSelection = async (event) => {.... 和 await setValues... 不起作用?
    • 这是 Reactjs 的一个怪癖。设置状态始终是异步的,但函数本身不返回承诺。所以你等不及了。
    猜你喜欢
    • 2023-04-02
    • 2020-04-19
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 2023-02-26
    相关资源
    最近更新 更多