【问题标题】:React - Array of Objects - Updating Object Property based on InputReact - 对象数组 - 根据输入更新对象属性
【发布时间】:2020-12-30 07:59:22
【问题描述】:

我正在创建一个锻炼日志应用程序,但在更新状态的嵌套属性时遇到了问题。这是我的状态...

this.state = {
     chosenExercises: [
                   {
                     id: 1, 
                     name: "Barbell Bench Press", 
                     type: "Strength", 
                     setCount: [1],
                     lbs: [], 
                     reps: []
                   },
                   {
                     id: 2,
                     name: "Dumbell Bench Press", 
                     type: "Strength", 
                     setCount: [1], 
                     lbs: [],
                     reps: []
                   }
                      ]
            } //End of state

//Function to update lbs from user input
     updateLbs = (lbs) => {
          //WHAT GOES HERE??
     }

用户输入是 2 个组件,它是父组件中表单的一部分。是否可以使用作为 props 传递的父组件中的更改处理程序来更新每个练习的每组 lbs?

这是我在完成特定练习后正在寻找的结果。

this.state = {
     chosenExercises: [
                   {
                     id: 1, 
                     name: "Barbell Bench Press", 
                     type: "Strength", 
                     setCount: [1, 2, 3, 4],
                     lbs: [135, 135, 155, 185], 
                     reps: [12, 12, 10, 8]
                   },
                   {
                     id: 2,
                     name: "Dumbell Bench Press", 
                     type: "Strength", 
                     setCount: [1], 
                     lbs: [],
                     reps: []
                   }
                      ]
            }

我尝试将 .find() 和 .filter() 一起使用,但我还没有那么好。感谢您的帮助。

【问题讨论】:

    标签: reactjs nested state


    【解决方案1】:

    只是示例如何更新 lbs 函数。我的想法是找到一个需要更新的对象并更新它们,在为 selectedExercises 设置状态之后,通过将更新的对象附加到其他对象。

    //Function to update lbs from user input
        updateLbs = (lbs, id) => {
            //WHAT GOES HERE??
    
            let chosenExercise = this.state.chosenExercises.find(chosenExercise => chosenExercise['id'] === 1);
    
            if (chosenExercise === undefined)
                return;
            
            //update lbs
            chosenExercise['lbs'] = lbs;
    
            let remainChosenExercise = this.state.chosenExercises.filter(chosenExercise => chosenExercise['id'] !== 1);
    
            this.setState({chosenExercise: [...remainChosenExercise, chosenExercise]});
        }
    

    【讨论】:

    • 这主要是可行的。但是,如果最后的组件依赖索引位置进行渲染,那么每次更新item的位置都会更改到组件列表的末尾。
    【解决方案2】:

    您需要有某种标识符才能知道您正在更新什么。无论是索引位置还是名称(假设名称是唯一的)或 id。在下面的示例中,我假设您通过 lbs 更新传递练习的名称。

    update = (lbs, name) => {
      setState((prevState) => {
        const update = {...prevState};
        const index = update.chosenExcercises.findIndex((excercise) => excercise.name === name)
        update[index] = {
          ...update[index],
          lbs: [...update[index].lbs, lbs]
        }
        return {chosenExcercises: update}
      })
    };
    

    【讨论】:

    • 这会引发错误,指出无法读取未定义的属性 findIndex。由于这个问题,这个项目成为了一场噩梦。我将尝试将所有内容放在一个组件中并以简单的方式更新状态。我真的很感谢您的帮助!
    • 登录update,看看函数运行时的状态。
    猜你喜欢
    • 1970-01-01
    • 2020-10-01
    • 2018-12-25
    • 1970-01-01
    • 2014-05-05
    • 2019-12-06
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    相关资源
    最近更新 更多