简体   繁体   English

当我的成分数组发生变化时如何重新渲染内容?

[英]How to re-render content when my array of ingredients changes?

I am trying to make a screen where users can edit recipes and one component is allowing users to edit the ingredients needed for the recipe.我正在尝试制作一个屏幕,用户可以在其中编辑食谱,其中一个组件允许用户编辑食谱所需的成分。

Here, I have the text input component which is a custom component and a trash icon that allows users to delete that ingredient.在这里,我有文本输入组件,它是一个自定义组件和一个允许用户删除该成分的垃圾桶图标。

<View style={styles.listLabelContainer}>
            <BoldedText style={styles.labelText}>Ingredients</BoldedText>
            <TouchableOpacity
              activeOpacity={0.5}
              onPress={() => {
                addListItemHandler(ingredients);
              }}
            >
              <Ionicons
                name={Platform.OS === "android" ? "md-add" : "ios-add"}
                size={23}
                color={Colours.primary}
              />
            </TouchableOpacity>
          </View>
          <View>
            {ingredients.map((ingredient, index) => (
              <ListItem key={index}>
                <View style={styles.ingredientInputContainer}>
                  <View style={styles.ingredientInput}>
                    <Input
                      autoCorrect
                      keyboardType="default"
                      returnKeyType="done"
                      required
                      identifier="recipeIngredient"
                      initialValue={ingredient}
                      onInputChange={() => {}}
                    />
                  </View>
                  <TouchableOpacity
                    style={styles.deleteButton}
                    activeOpacity={0.5}
                    onPress={() => {
                      deleteListItemHandler(ingredients, index);
                    }}
                  >
                    <Ionicons
                      name={
                        Platform.OS === "android" ? "md-trash" : "ios-trash"
                      }
                      size={23}
                      color={Colours.primary}
                    />
                  </TouchableOpacity>
                </View>
              </ListItem>
            ))}
          </View>
        </View>

The functions to delete and add an ingredient are as follows:删除和添加成分的功能如下:

const [ingredients, setIngredients] = useState(
    currentRecipe ? [...currentRecipe.ingredients] : []
  );

  const addListItemHandler = (arr) => {
    // add one empty string to end of array STEP
    setIngredients(arr.concat(""));
  };

  const deleteListItemHandler = (arr, index) => {
    // remove desired index ingredient STEP

    arr.splice(index, 1);
    setIngredients([...arr]);
  };

However, in the case where I have 5 ingredients and I choose to delete the 3rd ingredient, of array index 2, the array is updated accordingly.但是,在我有 5 种成分并且我选择删除数组索引 2 的第 3 种成分的情况下,数组会相应更新。 However, what is rendered is incorrect as the ingredient removed is the last ingredient and the ingredient to be removed is still present.但是,呈现的内容是不正确的,因为移除的成分是最后一种成分,而要移除的成分仍然存在。 My guess is that the value of the text input cannot be updated dynamically.我的猜测是文本输入的值不能动态更新。 However, is there a way to make this part of the code re-render whenever my ingredients array change so that the ingredients array is always the most updated one?但是,有没有办法让这部分代码在我的配料数组更改时重新渲染,以便配料数组始终是最新的? This would allow for the correct rendering of ingredients.这将允许正确呈现成分。

Edit: I realise the issue is because the initialValue prop of the custom Input component is not updating whenever the array changes.编辑:我意识到问题是因为自定义 Input 组件的 initialValue 属性在数组更改时不会更新。 Hence, what is displayed on the screen remains the same which causes the above error.因此,屏幕上显示的内容保持不变,导致上述错误。

Thank you for the help.感谢您的帮助。

What I can see is that you are mutating the state and it looks like your state is not synced with the UI.我可以看到您正在改变 state 并且看起来您的 state 没有与 UI 同步。

try something like this尝试这样的事情

const deleteListItemHandler = (arr, index) => {
    // remove desired index ingredient STEP
    const state = [...ingredients]
    state.splice(index, 1);
    setIngredients([...state]);
  };

or或者

const deleteListItemHandler = (arr, index) => {
    // remove desired index ingredient STEP

    setIngredients( oldState => [...oldState.splice(index, 1)]);
  };

You don't need to pass the array again您无需再次传递数组

const deleteListItemHandler = (index) => {
    ingredients.splice(index, 1);
    setIngredients([...ingredients]);
  };

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

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