Флажок «Реагировать на собственное асинхронное хранилище expo»

#typescript #react-native #expo #asyncstorage

Вопрос:

Я пытаюсь сохранить флажок в asyncstorage и прочитать его, но это не работает

Это компонент флажка, он получает ключ async storage @через реквизит

У меня есть несколько флажков, из-за этого я сделал компонент, я не знаю, является ли это основой

Флажок.tsx:

 export default function Checkbox({ storeId }: CheckboxProps) {
  const [isSelected, setIsSelected] = useState(false)
  const [color, setColor] = useState('#fd4e4e')

  function changeSelect() {
    setIsSelected(!isSelected)
  }

  React.useEffect(() => {
    const data = async () => {
      await readData(storeId)
      await storeData(isSelected, storeId)
    }

    data()
  }, [isSelected])

  React.useEffect(() => {
    const data = async () => {
      await readData(storeId)
      await storeData(isSelected, storeId)
    }

    data()
  }, [])

  const storeData = async (value: any, storeId: string) => {
    try {
      const jsonValue = JSON.stringify(value);
      await AsyncStorage.setItem(storeId, jsonValue);
    } catch (e) {
    }
  };

  const readData = async (storeId: string) => {
    try {
      const value = await AsyncStorage.getItem(storeId)
      if (value !== null) {
        if (value === 'true') {
          if (isSelected) {
            setIsSelected(true)
          }
        }
        if (value === 'false') {
          if (!isSelected) {
            setIsSelected(false)
          }
        }
      }
    } catch (e) {
    }
  }

  return (
    <View>
      <Pressable
        onPress={changeSelect}
        style={[styles.checkboxBase, { borderColor: color }, isSelected amp;amp; { backgroundColor: color }]}
      >
        {isSelected amp;amp; <Ionicons name="md-checkmark-sharp" size={40} color="white" style={styles.icon} />}
      </Pressable>
    </View>
  );
}
 

Ответ №1:

В своем readData методе вы написали условие, которое никогда не будет выполнено,

 const readData = async (storeId: string) => {
    try {
      const value = await AsyncStorage.getItem(storeId)
      if (value !== null) {
        if (value === 'true') {
          if (isSelected) { // remove this check. 
            setIsSelected(true)
          }
        }
        if (value === 'false') {
          if (!isSelected) { // not required 
            setIsSelected(false)
          }
        }
      }
    } catch (e) {
    }
  }
 

измените свой компонент на,

 function Checkbox({ storeId }) {
  const [isSelected, setIsSelected] = useState(false)
  const [color, setColor] = useState('#fd4e4e') // you are not using this setColor anywhere.

  const changeSelect = () => {
    storeData(!isSelected, storeId);
    setIsSelected(value => !value) // change value based on the previous value
  }

  React.useEffect(() => {
    readData(storeId)
  }, []);

  const storeData = async (value: any, storeId: string) => {
    try {
      const jsonValue = JSON.stringify(value);
      await AsyncStorage.setItem(storeId, jsonValue);
    } catch (e) { }
  };

  const readData = async (storeId: string) => {
    try {
      const value = await AsyncStorage.getItem(storeId)
      if (value != null) {
        setIsSelected(JSON.parse(value)); // set the isSelected to the value from storage
      }
    } catch (e) { }
  }

  return (
    <Pressable
      onPress={changeSelect}
      style={[{
        width: 20,
        height: 20,
        borderRadius: 2,
        borderWidth: 2,
        alignItems: 'center',
        justifyContent: 'center',
        margin: 5
      }, { borderColor: color }, isSelected amp;amp; { backgroundColor: color }]}
    >
      {isSelected amp;amp; <Text>✔️</Text>}
    </Pressable>
  );
}
 

Другая ошибка в коде : у вас есть isSelected as false по умолчанию, и вы также вызывали storeData метод при монтировании. Что в конечном итоге всегда ставит вас isSelected в ложное положение.

Комментарии:

1. Это все равно не работает

2. Когда я перезагружаю приложение, значения снова становятся ложными

3. @robinnlmn попробуйте обновленный код

4. Спасибо! Теперь это работает.

5. @robinnlmn Любезно примите ответ, если он окажется полезным 🙂