簡體   English   中英

在本機反應中更新狀態數組

[英]Updating state array in react native

我正在嘗試跟蹤所選練習的列表,然后如果所選練習在列表中,則呈現“添加”,如果不在列表中,則呈現“未添加”。 當尚未包含該練習時,我將其添加到chosenExerciseArray中,如果包含,則將其刪除。 當我使用console.log(chosenExerciseArray)時,它會正確顯示列表,但如果我使用setChosenExercises(chosenExerciseArray)狀態不會正確更新,並且chosenExerciseArray以某種方式停止記錄正確的數組。

我還嘗試將 selectedExerciseArray 添加為chosenExerciseArray依賴項,但這會導致無限循環。 我真的不確定這里發生了什么,但我相信這是我對狀態的理解的問題。

編輯: TouchableOpacity 在地圖內,這也可能是問題,但我不確定如何

<View style={styles.exerciseheadericongroup}>
   <TouchableOpacity
       onPress={() => {
         if(!chosenExerciseArray.includes(exercise.id)) {
            chosenExerciseArray.push(exercise.id);
         } else {
            for(var i=0; i<chosenExerciseArray.length; i++) {
               if(chosenExerciseArray[i] === exercise.id) {
                 chosenExerciseArray.splice(i, 1);
               }
             }
          }
          console.log(chosenExerciseArray);
        }}
    >
    {chosenExercises.includes(exercise.id) ? (
       <Text>added</Text>
    ) : (
       <Text>not added</Text>
    )}
  </TouchableOpacity>
</View>

如 React 文檔中所述

state 是對應用更改時組件狀態的引用。 它不應該直接突變。 相反,應該通過基於狀態和道具的輸入構建一個新對象來表示更改。 [關聯]

我希望我能更好地解釋它,但基本上這意味着使用.push操作chosenExerciseArray然后執行setChosenExerciseArray(chosenExerciseArray)弄亂狀態處理。 您需要復制chosenExerciseArray並對其進行操作,然后使用操作后的副本設置新狀態。 我創建了兩個示例供您查看:

示例 1使用不同的邏輯,其中added是練習對象本身的一部分,因此不需要使用chosenExerciseArray來跟蹤是否添加了練習。 這也更有效率,因為您不需要檢查一個練習是否在chosenExerciseArray中。

 import React, { useState } from "react"; import { Pressable, StyleSheet } from "react-native"; import { Text, View } from "../components/Themed"; interface Exercise { id: string; name: string; added: boolean; } const updateExerciseArray = (exercises: Exercise[], exercise: Exercise) => { // Shallow copy const updatedExercises = [...exercises]; // Manipulate the copy return updatedExercises.map((updatedExercise) => { if (updatedExercise.id === exercise.id) { // Shallow copy of object in array where added is negated return { ...updatedExercise, added: !updatedExercise.added }; } return updatedExercise; }); }; export default function Example1() { const [exercises, setExercises] = useState<Exercise[]>([ { id: "1", name: "Pushups", added: false }, { id: "2", name: "Situps", added: false }, { id: "3", name: "Squats", added: false }, { id: "4", name: "Pullups", added: false }, { id: "5", name: "Leg Raises", added: false }, { id: "6", name: "Plank", added: false }, { id: "7", name: "Burpees", added: false }, { id: "8", name: "Jumping Jacks", added: false }, { id: "9", name: "Wall Sit", added: false }, ]); return ( <View style={styles.container}> {exercises.map((exercise) => { return ( <Pressable key={exercise.id} onPress={() => { setExercises(updateExerciseArray(exercises, exercise)); }} style={styles.row} > <Text style={styles.text}>{exercise.name}</Text> <Text style={styles.text}> {exercise.added ? "Added" : "Not added"} </Text> </Pressable> ); })} </View> ); } const styles = StyleSheet.create({ container: { paddingHorizontal: 50, flex: 1, backgroundColor: "#fff", justifyContent: "center", }, row: { marginVertical: 10, flexDirection: "row", justifyContent: "space-between", }, text: { fontSize: 20, }, });

示例 2使用適合您當前實現的解決方案。

 import React, { useState } from "react"; import { Pressable, StyleSheet } from "react-native"; import { Text, View } from "../components/Themed"; interface Exercise { id: string; name: string; } const updateExerciseArray = ( chosenExerciseArray: string[], exerciseToChange: Exercise ) => { // Shallow copy const updatedChosenExerciseArray = [...chosenExerciseArray]; if (updatedChosenExerciseArray.includes(exerciseToChange.id)) { // Remove the exercise from the array return updatedChosenExerciseArray.filter( (exerciseId) => exerciseId !== exerciseToChange.id ); } else { // Append the exercise to the array return [...updatedChosenExerciseArray, exerciseToChange.id]; } }; export default function Example2() { const [exercises] = useState<Exercise[]>([ { id: "1", name: "Pushups" }, { id: "2", name: "Situps" }, { id: "3", name: "Squats" }, { id: "4", name: "Pullups" }, { id: "5", name: "Leg Raises" }, { id: "6", name: "Plank" }, { id: "7", name: "Burpees" }, { id: "8", name: "Jumping Jacks" }, { id: "9", name: "Wall Sit" }, ]); const [chosenExerciseArray, setChosenExerciseArray] = useState<string[]>([ "1", "2", ]); return ( <View style={styles.container}> {exercises.map((exercise) => { return ( <Pressable key={exercise.id} onPress={() => { setChosenExerciseArray( updateExerciseArray(chosenExerciseArray, exercise) ); }} style={styles.row} > <Text style={styles.text}>{exercise.name}</Text> <Text style={styles.text}> {chosenExerciseArray.includes(exercise.id) ? "Added" : "Not added"} </Text> </Pressable> ); })} </View> ); } const styles = StyleSheet.create({ container: { paddingHorizontal: 50, flex: 1, backgroundColor: "#fff", justifyContent: "center", }, row: { paddingVertical: 10, flexDirection: "row", justifyContent: "space-between", }, text: { fontSize: 20, }, });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM