繁体   English   中英

React.js:更新嵌套对象的状态

[英]React.js : Updating State of Nested Object

前端 -前端单击星标后,我想使用星号的新评级值更新嵌套对象的状态。

我尝试了很多东西,但它不起作用,因为状态是不可变的。

嵌套状态

有人可以建议我如何更新嵌套对象中的值

onStarClicked = (kTypName, subItemId1, newRating) => {
//console.log(subItemId.split("_"));
let evaluation = subItemId1.split("_")[0];
let subItemId = subItemId1.split("_")[1];
console.log(subItemId);
const r = { ...this.state.ratings };
let kT = r.knowledgeTypes;
let sub = '', kTN = '', kIN = '';
kT.map(knowledgeType => {
  //console.log(knowledgeType.knowledgeTypeId);
  knowledgeType.knowledgeItems.map(knowledgeItem => {
    //console.log(knowledgeItem.knowledgeItemId);
    knowledgeItem.subItems.map(knowledgeSubItem => {
      //console.log(knowledgeSubItem.subItemId);
      if (subItemId === knowledgeSubItem.subItemId) {
        kTN = knowledgeType.knowledgeTypeName;
        kIN = knowledgeItem.knowledgeItemName;
        sub = knowledgeSubItem;
        if (evaluation === "self") {
          sub.evaluation.self.rating = newRating;
        }
        else if (evaluation === "evaluator") {
          sub.evaluation.evaluator.rating = newRating;
        }

        //alert(evaluation + subItemId + ' ' + newRating);
        //return;
      }
    })
  })

});


this.setState({
  ...this.state,
  ratings: {
    ...this.state.ratings,
    knowledgeTypes: [
      ...this.state.ratings.knowledgeTypes,
      this.state.ratings.knowledgeTypes.filter(kt => kt.knowledgeTypeName !== kTN),
      {
        ...this.state.ratings.knowledgeTypes.knowledgeItems.
          filter(ki => ki.knowledgeItemName !== kIN),
        knowledgeItems: {
          ...this.state.ratings.knowledgeTypes.knowledgeItems.subItems.
            filter(si => si.subItemId !== subItemId),
          sub
        }
      }]
  }
});

}

您基本上必须创建一个新的knowledgeTypes空数组,并使用当前状态来查找需要使用Object.keys/map/filter函数更改的状态项。

您将在变量中使用当前状态并仅修改该变量。 您可能不会以任何方式弄乱实际的状态对象。

完成后,只需将其附加到空数组。 然后您可以将新数组 setState() 设置为实际的 state 属性。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      financialYear: "2019-20",
      quarter: "Q1",
      isCurrentQuarter: true,
      knowledgeTypes: [
        {
          knowledgeTypeName: "Technology",
          knowledgeItems: [
            {
              knowledgeItemName: "Java",
              subItems: [
                {
                  subItemId: "2",
                  subItemName: "Collections",
                  evaluation: {
                    self: {
                      ntnet: "Joe",
                      rating: 1,
                      isEditable: true
                    }
                  }
                }
              ]
            }
          ]
        }
      ]
    };
  }

  handleClick = e => {
    const { knowledgeTypes } = this.state;

    // transformation
    const itemToChange = knowledgeTypes.map(item => {
      if (item.knowledgeTypeName === "Technology") {
        return item;
      }
    });
    const currItems = itemToChange[0].knowledgeItems[0].subItems;
    const subItem = currItems.map(item => {
      if (item.subItemId === "2") {
        return item;
      }
    });
    const person = subItem[0].evaluation;
    person.self.rating = 55; //change

    const newKnowledgeTypes = [];
    knowledgeTypes.map(item => {
      if (item.knowledgeTypeName === "Technology") {
        newKnowledgeTypes.push(itemToChange);
      }
      newKnowledgeTypes.push(item);
    });

    this.setState({
      knowledgeTypes: newKnowledgeTypes
    });

    console.log(this.state);
  };

  render() {
    return (
      <div>
        MyComponent
        <button onClick={this.handleClick}>Hello</button>
      </div>
    );
  }
}


沙箱可以在https://codesandbox.io/s/musing-dew-8r2vk上找到。

注意:建议您不要使用嵌套状态对象,因为状态对象更轻量级,因此它们没有性能方面的考虑。

import React, { Component } from 'react';
import Auxilary from '../../../hoc/Auxilary/auxilary';
import KnowledgeItems from '../KnowledgeItems/KnowledgeItems';
import Tabs from 'react-bootstrap/Tabs';
import Tab from 'react-bootstrap/Tab';
import knowledge from '../../../assests/staticdata.json';

import './QuarterLog.css';

class QuarterLog extends Component {

  constructor() {
    super();
    this.state = {
      "financialYear": "",
      "quarter": "",
      "isCurrentQuarter": "",
      "knowledgeTypes": []
    }
  }

  onStarClicked = (kTypName, kItemName, subItemIdName, newRating) => {
    let evaluation = subItemIdName.split("_")[0];
    let subItemId = subItemIdName.split("_")[1];

    const { knowledgeTypes } = this.state;

    // transformation
    let knowledgeTypeToChange = knowledgeTypes.map(kType => {
      if (kType.knowledgeTypeName === kTypName) {
        return kType;
      }
    });

    knowledgeTypeToChange = knowledgeTypeToChange.filter(function (element) {
      return element !== undefined;
    });

    console.log(knowledgeTypeToChange[0]);
    let knowledgeItemToChange = knowledgeTypeToChange[0].knowledgeItems.map(item => {
      if (item.knowledgeItemName === kItemName) {
        return item;
      }
    });

    knowledgeItemToChange = knowledgeItemToChange.filter(function (element) {
      return element !== undefined;
    });

    let knowledgeSubItem = knowledgeItemToChange[0].subItems.map(subItem => {
      if (subItem.subItemId === subItemId) {
        return subItem;
      }
    });

    knowledgeSubItem = knowledgeSubItem.filter(function (element) {
      return element !== undefined;
    });

    console.log(knowledgeSubItem);

    let personEvaluations = knowledgeSubItem[0].evaluation;

    if (evaluation === "self") {
      personEvaluations.self.rating = newRating.toString(); //change
    }
    else if (evaluation === "evaluator") {
      personEvaluations.evaluator.rating = newRating.toString(); //change
    }

    const newKnowledgeTypes = [];
    knowledgeTypes.map(item => {
      if (item.knowledgeTypeName === kTypName) {
        newKnowledgeTypes.push(knowledgeTypeToChange[0]);
      }
      else
        newKnowledgeTypes.push(item);
    });

    this.setState({
      knowledgeTypes: newKnowledgeTypes
    });

    console.log(this.state);

  }

  componentDidMount() {
    // TODO: remove staticdata.js and call REST API and set the response in state
    this.setState({
      ...this.state,
      "financialYear": knowledge.financialYear,
      "quarter": knowledge.quarter,
      "isCurrentQuarter": knowledge.isCurrentQuarter,
      "knowledgeTypes": knowledge.knowledgeTypes
    })

  }

  onSubmitRatings = () => {
    console.log(this.state);
  }

  render() {
    let data = knowledge; //remove this code, once REST API is implemented

    const posts = this.state.knowledgeTypes.map(knowledgeType => {
      return (
        <Tab key={knowledgeType.knowledgeTypeName} eventKey={knowledgeType.knowledgeTypeName}
          title={knowledgeType.knowledgeTypeName}>
          <KnowledgeItems
            kTypeName={knowledgeType.knowledgeTypeName}
            kItems={knowledgeType.knowledgeItems}
            ratings={this.state.ratings}
            onstarclicked={this.onStarClicked}
          />
        </Tab>)
    });

    return (
      <Auxilary>
        <div className="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
          <div><h1>Financial Year : {data.financialYear}</h1></div>
          <div><h2>Quarter : {data.quarter}</h2></div>
        </div>
        <div>
          <Tabs defaultActiveKey="Domain" id="uncontrolled-tab-example">
            {posts}
          </Tabs>
        </div>
        <button onClick={this.onSubmitRatings}> Submit </button>
      </Auxilary>
    );
  }
}

export default QuarterLog;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM