【问题标题】:React Native - Unable to update a new state inside items individuallyReact Native - 无法单独更新项目内的新状态
【发布时间】:2021-02-06 11:51:52
【问题描述】:

我从一个包含练习列表的 api 中提取数据,这里是一个示例练习对象。

    {
        pivot_id:1,
        id:1,
        image_path: "exercise\/images\/q3YaO7uuFYgZDFg7fnVpn3eYxrb5oUZeKwE6mNf7.png",
        name:"Smitham PLC",
        duration:423,
        duration_per_rep:5,
        intensity:{
          id:2,
          intensity: "Moderate Resistance Training",
          met_value:4.5
        },
        image:"https:\/\/s3-eu-west-1.amazonaws.com\/fitness-concierge\/exercise\/images\/q3YaO7uuFYgZDFg7fnVpn3eYxrb5oUZeKwE6mNf7.png",
        kcal:5,
  },

我创建了一个默认值为 60 的 customDuration 状态,我想通过使用按钮添加一个以 30 秒为增量的持续时间来将其添加到每个锻炼对象。但是,我在只更新一个特定项目时遇到了问题。

例如,我渲染了两个项目,当我按下 + 按钮为它所做的练习添加 30 秒时,它从 60 到 90 秒,但是当我去第二个添加一些时间时列表中的项目将从 60 到 120 出现问题。

 addDuration(item, index) {
    let newArray = [...this.state.warm_up_exercises];
    newArray[index] = { 
        ...newArray[index], 
        customDuration: this.state.customDuration = this.state.customDuration + 30,
        storeValues: true,
        workoutStoreType: 'duration',
    };
    this.setState({
        warm_up_exercises: newArray,
    });
}

上面是我用来为练习添加持续时间的函数,我尝试过 item.customDuration = item.customDuration + 30 但我只是在控制台中得到 NaN。

在我的映射函数中,我的自定义持续时间显示如下

<Text>{{ item.customDuration }}</Text>

我已经为此苦苦挣扎了几天,非常感谢您的帮助。我想要实现的只是做到这一点,因此当我将值添加到数组时,它将更新该项目并且对其他项目没有影响。

提供更多上下文的附加代码:

My constructor:

constructor(props) {
  super(props) {
    warm_up_exercises: [],
    selected_warm_up_exercises: [],
    repsValue: 0,
    setsValue: 0,
    restValue: 0,
    workoutStoreType: "",
    customDuration: 60,
  }
}
Were I call the function: 

<TouchableOpacity onPress={() => this.addDuration(item, index)}>
   <AntDesign name="pluscircle" size={22} color={Colours.type.primary_colour}  />
</TouchableOpacity>

【问题讨论】:

    标签: arrays reactjs react-native mapping increment


    【解决方案1】:

    首先,您没有正确初始化您的状态。它应该是一个对象,具有练习数组作为属性。像这样写:

    constructor(props) {
      super(props) {
        this.state = {
         exercises: [],
         repsValue: 0,
         setsValue: 0,
         restValue: 0,
         workoutStoreType: "",
         customDuration: 60,
        }
      }
    }
    

    每次您增加状态时,您不仅会改变它,而且还会将 customDuration 放入每个实体。问题出在这里:

    customDuration: this.state.customDuration = this.state.customDuration + 30
    

    为了做对,你只需要写:

    customDuration: this.state.customDuration + 30
    

    然后,要增加状态,您应该单独执行:

    this.setState({
            exercises: newArray,
            customDuration: this.state.customDuration + 30
        });
    

    如果您需要为每个项目设置 customDuration,您还需要以相同的方式更改状态,但需要稍作改动:

    addDuration(item, index) {
        let newArray = [...this.state.exercises]
        newArray[index] = {
            ...newArray[index],
            customDuration: newArray[index].customDuration ? newArray[index].customDuration + 30 : 90,
            storeValues: true,
            workoutStoreType: 'duration',
        };
        this.setState({
            exercises: newArray,
        });
    }
    

    然后从初始状态中移除 customDuration。这样,您将增加 30,并在第一次增加时放入 90

    【讨论】:

    • 谢谢我已经实现了。但 customDuration 值仍在更新下一项。因此,当我从 60 - 90 更新第一个项目,然后去更新数组中的下一个项目时,它会从 60 - 120 更新。我需要在状态末尾添加一个 [index] 还是添加 item.customDuration在那个函数的某个地方?
    • 我觉得有些误会。我以为你想要一个全局持续时间,当你增加时,它会增加。请告诉我您是否想为每个练习设置一个 customDuration,我会更新我的答案。另外,我现在看到,您初始化状态的方式存在问题
    • 是的,这就是我的目标,是为每个练习设置一个 customDuration,所以当我为一个练习增加 customDuration 时,它只会更新那个练习,对其他练习没有影响,所以它只是单独更新它们。抱歉,如果它让我在全球范围内想要它。
    • @TrevorStrong 我更新了我的答案,如果我理解正确,请告诉我
    • 没有你的答案完成了这项工作。我的假设是我需要创建一个 customDuration 状态才能将其添加到数组中,但是你完成它的方式很棒。谢谢你的帮助。
    猜你喜欢
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 2020-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多