反应 useState 不更新状态
React useState not updating state
我正在用一个电影应用程序训练 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 方法已经为另一个组件中的 Load More Button 做好了准备,在这种情况下,它将向数组添加更多项目。某处应该有 useEffect 吗?
谢谢
问题出在 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
};
});
}
我正在用一个电影应用程序训练 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 方法已经为另一个组件中的 Load More Button 做好了准备,在这种情况下,它将向数组添加更多项目。某处应该有 useEffect 吗? 谢谢
问题出在 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
};
});
}