根据从 React 中的 redux 读取的数据更新状态
Updating state from the data that was read from redux in React
这是我为项目构建的教育组件。目前,education_data 是在第二次重新渲染时从 redux 状态中读取的。我的目标是为 education_data 中的每个单独条目添加一个可见性按钮。 Education_data 是一个对象数组。该按钮将允许用户隐藏链接到他们希望隐藏的索引的数据。我有另一个名为 education_vis 的变量,它存储一个大小为 education_data 的数组,最初需要将其保存到状态中以隐藏渲染中的元素。这种使用 useState 的保存与使用 useSelector 从 redux 数据中读取的数据不同步。
handleChange 工作正常,唯一需要做的就是将 education_vis 中的数据复制到一个状态中,这样我就可以在三元运算符中使用它来隐藏组件。
import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from "react-redux";
import * as educationActions from "../../actions/educationActions";
import DeleteButton from "./deleteButton";
import UpdateButton from "./updateButton";
import VisibilityOffIcon from '@material-ui/icons/VisibilityOff';
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import EducationForm from "../forms/updateForms/educationForm";
const Education = () => {
const dispatch = useDispatch();
useEffect(() => {
const userEducation = async () => {
await dispatch(educationActions.getEducation('60fcc884bbed863d20b02573'));
};
userEducation();
}, [dispatch]);
const education_data = useSelector((state) => state.education.education);
var education_vis = Array(education_data.length);
if(education_vis[0] === undefined){
for(var i = 0; i < education_data.length; i++){
education_vis[i] = true;
}
}
const handleChange = (index) => {
education_vis[index] = !education_vis[index];
console.log(education_vis);
}
return (
<Router>
<div>
<p> Education </p>
<hr />
{education_data.map((value, index) => {
return (
<div>
<VisibilityOffIcon onClick = {()=>handleChange(index)} />
{education_vis[index] ? <div key={index}>
<p>{ value.university_name }, { value.university_city }, { value.university_state } { value.month_begin } { value.year_begin } - { value.month_end } { value.year_end }</p>
<p>{ value.degree_name } in { value.domain_name } { value.GPA }</p>
<DeleteButton elementId = { value._id } page = { "Education" }/>
<Link to={ `/education/${value._id}/update` } ><UpdateButton /></Link>
</div> : null}
</div>
)
})}
</div>
<Switch>
<Route path="/education/:elementId/update">
<EducationForm />
</Route>
</Switch>
</Router>
)
}
export default Education
示例 education_data 的外观如下。同样的 education_vis 将是 [true, true]
/* var education_data = [
{
degree_name: "Masters",
domain_name: "Information Sciences and Technology",
school_name: "iSchool",
university_name: "Rochester Institute of Technology",
university_city: "Rochester",
university_state: "NY",
university_country: "USA",
year_begin: "2019",
month_begin: "August",
year_end: "2021",
month_end: "December",
GPA: "3.8",
},{
degree_name: "Bachelors",
domain_name: "CS",
school_name: "DSCE",
university_name: "VTU",
university_city: "Bangalore",
university_state: "Karnataka",
university_country: "India",
year_begin: "2014",
month_begin: "August",
year_end: "2018",
month_end: "June",
GPA: "3.8",
}] */
下面是我尝试使用 useStates() 设置状态的方法。
const [educationVisibility, setEducationVisibility] = useState(education_vis);
useEffect(() => {
setEducationVisibility(education_vis)
},[education_vis])
我试图在单击 时实现组件的隐藏/显示功能。为此,我需要将 education_vis 上传到将启用组件重新渲染的状态,并且需要帮助才能做到这一点。
当你做 education_vis[index] === !education_vis[index]
时,你正在变异 education_vis
。所以现在 useEffect
不会触发,因为 education_vis
从未 改变 。它只是突变所以对象的引用仍然是一样的。
React 本质上使用 Object.is
依赖项来比较依赖项值,因此它将 return 为假,因此 useEffect
中的代码不会 运行。
此外,我看到您为此使用了 useEffect
,但您不需要,因为您已经有了 handleChange
回调。您可以从那里更新状态。
const [educationVisibility, setEducationVisibility] = useState(education_vis);
const handleChange = (index) => {
education_vis[index] = !education_vis[index];
setEducationVisibility([...education_vis]); // using spread to get a new instance of the array
}
您还可以使用 immer 库来帮助您完成其中的一些操作。但那是,如果你真的需要它。当您拥有复杂的数据结构时,它确实有帮助。
这是我为项目构建的教育组件。目前,education_data 是在第二次重新渲染时从 redux 状态中读取的。我的目标是为 education_data 中的每个单独条目添加一个可见性按钮。 Education_data 是一个对象数组。该按钮将允许用户隐藏链接到他们希望隐藏的索引的数据。我有另一个名为 education_vis 的变量,它存储一个大小为 education_data 的数组,最初需要将其保存到状态中以隐藏渲染中的元素。这种使用 useState 的保存与使用 useSelector 从 redux 数据中读取的数据不同步。 handleChange 工作正常,唯一需要做的就是将 education_vis 中的数据复制到一个状态中,这样我就可以在三元运算符中使用它来隐藏组件。
import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from "react-redux";
import * as educationActions from "../../actions/educationActions";
import DeleteButton from "./deleteButton";
import UpdateButton from "./updateButton";
import VisibilityOffIcon from '@material-ui/icons/VisibilityOff';
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import EducationForm from "../forms/updateForms/educationForm";
const Education = () => {
const dispatch = useDispatch();
useEffect(() => {
const userEducation = async () => {
await dispatch(educationActions.getEducation('60fcc884bbed863d20b02573'));
};
userEducation();
}, [dispatch]);
const education_data = useSelector((state) => state.education.education);
var education_vis = Array(education_data.length);
if(education_vis[0] === undefined){
for(var i = 0; i < education_data.length; i++){
education_vis[i] = true;
}
}
const handleChange = (index) => {
education_vis[index] = !education_vis[index];
console.log(education_vis);
}
return (
<Router>
<div>
<p> Education </p>
<hr />
{education_data.map((value, index) => {
return (
<div>
<VisibilityOffIcon onClick = {()=>handleChange(index)} />
{education_vis[index] ? <div key={index}>
<p>{ value.university_name }, { value.university_city }, { value.university_state } { value.month_begin } { value.year_begin } - { value.month_end } { value.year_end }</p>
<p>{ value.degree_name } in { value.domain_name } { value.GPA }</p>
<DeleteButton elementId = { value._id } page = { "Education" }/>
<Link to={ `/education/${value._id}/update` } ><UpdateButton /></Link>
</div> : null}
</div>
)
})}
</div>
<Switch>
<Route path="/education/:elementId/update">
<EducationForm />
</Route>
</Switch>
</Router>
)
}
export default Education
示例 education_data 的外观如下。同样的 education_vis 将是 [true, true]
/* var education_data = [
{
degree_name: "Masters",
domain_name: "Information Sciences and Technology",
school_name: "iSchool",
university_name: "Rochester Institute of Technology",
university_city: "Rochester",
university_state: "NY",
university_country: "USA",
year_begin: "2019",
month_begin: "August",
year_end: "2021",
month_end: "December",
GPA: "3.8",
},{
degree_name: "Bachelors",
domain_name: "CS",
school_name: "DSCE",
university_name: "VTU",
university_city: "Bangalore",
university_state: "Karnataka",
university_country: "India",
year_begin: "2014",
month_begin: "August",
year_end: "2018",
month_end: "June",
GPA: "3.8",
}] */
下面是我尝试使用 useStates() 设置状态的方法。
const [educationVisibility, setEducationVisibility] = useState(education_vis);
useEffect(() => {
setEducationVisibility(education_vis)
},[education_vis])
我试图在单击 时实现组件的隐藏/显示功能。为此,我需要将 education_vis 上传到将启用组件重新渲染的状态,并且需要帮助才能做到这一点。
当你做 education_vis[index] === !education_vis[index]
时,你正在变异 education_vis
。所以现在 useEffect
不会触发,因为 education_vis
从未 改变 。它只是突变所以对象的引用仍然是一样的。
React 本质上使用 Object.is
依赖项来比较依赖项值,因此它将 return 为假,因此 useEffect
中的代码不会 运行。
此外,我看到您为此使用了 useEffect
,但您不需要,因为您已经有了 handleChange
回调。您可以从那里更新状态。
const [educationVisibility, setEducationVisibility] = useState(education_vis);
const handleChange = (index) => {
education_vis[index] = !education_vis[index];
setEducationVisibility([...education_vis]); // using spread to get a new instance of the array
}
您还可以使用 immer 库来帮助您完成其中的一些操作。但那是,如果你真的需要它。当您拥有复杂的数据结构时,它确实有帮助。