#javascript #reactjs #react-native
Вопрос:
Я пытаюсь использовать AsyncStorage для извлечения моих задач из крючка useEffect. Если нет задач(имеется в виду задача = = = []), то в текстовом компоненте отображается надпись «Добавить задачу».
Изображение приложения на выставке
Изначально для задач установлено значение «[]» внутри крючка useState. Когда метод addItem() вызывается onPress, задачи не загружаются.
Я не знаю, почему это происходит…
export default function App() { const [todo, setTodo] = useState(''); const [todos, setTodos] = useState([]); useEffect(() =gt; { _retrieveData(); }, [todos]); const addItem = (newTodo) =gt; { if (newTodo.length === 0) { Alert.alert( 'Enter a String', 'You have entered a string with 0 characters', [{ text: 'Okay', style: 'default' }] ); } else { console.log(newTodo); let newTodos = [newTodo, ...todos]; setTodo(''); _storeData(JSON.stringify(newTodos)); } }; const deleteTodo = (idx) =gt; { setTodos(todos.filter((todo, id) =gt; id !== idx)); }; const _storeData = async (value) =gt; { try { await AsyncStorage.setItem('TASKS', value); } catch (error) { // Error saving data console.log(e); } }; const _retrieveData = async () =gt; { try { const value = await AsyncStorage.getItem('TASKS'); if (value !== null) { // We have data!! setTodos(JSON.parse(value)); console.log(value); } } catch (error) { // Error retrieving data console.log(error); } }; return ( lt;TouchableWithoutFeedback onPress={() =gt; { Keyboard.dismiss(); }} gt; lt;View style={styles.outerContainer}gt; lt;Text style={styles.header}gt;TODOlt;/Textgt; lt;View style={styles.container}gt; lt;TextInput placeholder='new todo' style={styles.input} value={todo} onChangeText={(text) =gt; { setTodo(text); }} gt;lt;/TextInputgt; lt;Button title='Add' onPress={() =gt; addItem(todo)}gt;lt;/Buttongt; lt;/Viewgt; lt;ScrollView style={styles.scrollView}gt; {todos === [] ? ( lt;Viewgt; lt;Textgt;Add a todo!lt;/Textgt; lt;/Viewgt; ) : ( todos.map((todo, idx) =gt; ( lt;View style={styles.todo} key={idx}gt; lt;Text style={styles.todoText}gt;{todo}lt;/Textgt; lt;View style={styles.delete}gt; lt;Button color='red' title='Delete' onPress={() =gt; deleteTodo(idx)} gt;lt;/Buttongt; lt;/Viewgt; lt;/Viewgt; )) )} lt;/ScrollViewgt; lt;/Viewgt; lt;/TouchableWithoutFeedbackgt; ); }
Комментарии:
1. Вы никогда не вызываете setTodos в дополнение
Ответ №1:
Не используйте переданное todo
значение newTodo
, так как setState
оно async
не выполняется немедленно, поэтому вы можете использовать текущее заданное todo
значение вместо переданного старого значения,
const addItem = (newTodo) =gt; { if (todo.length === 0) { Alert.alert( 'Enter a String', 'You have entered a string with 0 characters', [{ text: 'Okay', style: 'default' }] ); } else { console.log(todo); let newTodos = [todo, ...todos]; setTodo(''); _storeData(JSON.stringify(newTodos)); setTodos(newTodos); } };
Комментарии:
1. Но будет ли это гарантировать, что мои данные также будут синхронизированы с хранилищем ? Или это просто в постоянных задачах? Потому что в следующий раз, когда я открою приложение, _retrieveData загрузит данные в todos с помощью setTodos ?
2. о, так что вы получаете
// Error retrieving data
всегда, так как он не может получить данные из AsynStore3. попробуйте
[todos, todo]
использовать эффект4. Хорошо, спасибо, я так и сделаю
5. извините, Нитин, на самом деле я не могу воспроизвести эту проблему здесь, в моей местной среде, поэтому просто гадаю