【问题标题】:Updating state from the data that was read from redux in React从 React 中从 redux 读取的数据更新状态
【发布时间】:2021-11-23 12:36:33
【问题描述】:

这是我为一个项目构建的教育组件。目前,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 上传到能够重新渲染组件的状态。

标签: reactjs redux react-hooks use-state


【解决方案1】:

当您更改education_vis[index] === !education_vis[index] 时,您正在变异education_vis。所以现在useEffect 不会触发,因为education_vis 从未更改。它只是变异了,所以对象的引用还是一样的。

React 本质上在依赖项上使用Object.is 来比较依赖值,因此它将返回 false,因此 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 库来帮助您完成其中一些操作。但也就是说,如果你真的需要它。当您拥有复杂的数据结构时,它确实会有所帮助。

【讨论】:

  • 谢谢!使用您的建议和 setState 回调,我能够实现我想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-09
  • 1970-01-01
  • 1970-01-01
  • 2020-06-10
  • 2019-01-15
  • 2019-05-30
  • 1970-01-01
相关资源
最近更新 更多