添加编辑后的最低可重复性示例:https://snack.expo.dev/@hdorra/code

我希望每个人都能接触到零食.因此,如果您添加一项任务,您可以看到它显示在日志(log)中.点击圆圈,它将显示为True(表示已被点击).保存并刷新,所有内容都将存储(任务),但复选框不会.我剥离了代码,使其尽可能少,但它显示了问题.

我已经为这个错误纠结了好几天了.我是一个相对较新的堆栈溢出,所以如果我的问题不清楚或我没有用正确的格式提问,我深表歉意.我正在try 创建一个在react 本机的待办应用程序,这是使用异步存储.我创建了一个切换按钮,用于将切换保存到某个状态.此按钮位于组件中:

 const [checkBoxState, setCheckBoxState] = React.useState(false);

 const toggleComplete = () => {

        setCheckBoxState(!checkBoxState)
        handleEdit();
        console.log(checkBoxState)

    }

当用户判断它时-似乎正确地在控制台中显示为标记为真和假. 然后,将其传递给编辑处理程序以更新数组,控制台再次显示它是正确的状态:

  const handleEdit = () => {
        props.editHandler(props.todoKey, text, checkBoxState);
        console.log(text2, checkBoxState)
    };

然后,它显示它已正确保存:

 const [todos, setTodos] = React.useState([]);
 const handleEdit = (todoKey, text, newStatus) => {
        const newTodos = [...todos];
        const index = newTodos.findIndex(todos => todos.key === todoKey);
        newTodos[index] = Object.assign(newTodos[index], {title: text, status: newStatus});
        setTodos(newTodos);
    
        console.log(todos, newStatus)
    };

保存到设备并加载的异步函数如下: 要保存:

const saveTodoToUserDevice = async (todos) => {
        try {
            const stringifyTodos = JSON.stringify(todos);
            await AsyncStorage.setItem('todos', stringifyTodos);
        } catch (error) {
            console.log(error);
        }
    };

要从设备加载,请执行以下操作:

const getTodosFromUserDevice = async () => {
        try {
            const todos = await AsyncStorage.getItem('todos');
            if (todos != null) {
                setTodos(JSON.parse(todos));
                console.log("loaded successfully");
            }
        } catch (error) {
            console.log(error);
        }
    };

这就是问题所在--我得到的控制台日志(log)显示它已被正确保存和加载.但是,当我刷新时,复选框状态根本没有保存,只保存了标题文本(因此它正在保存,但复选框始终为假(初始状态设置).如果我点击TRUE,它将显示为TRUE,然后当我刷新时,它将返回FALSE.

我花了一天又一天的时间在这上面,但我还是想不通.任何方向都会有帮助谢谢!

推荐答案

我已经判断了你的code,发现你在不同的地方犯了一些错误.在Task.js中,你可以没有checkBoxState.为此,将statusTask作为props传递,同时在FlatList中呈现它,如下所示:

<Task
  key={item.key}
  todoKey={item.key}
  title={item.title}
  status={item.status}
  editHandler={handleEdit}
  pressHandler={handleDelete}
/>

然后,如下所示,更改按钮以切换status,这样您就可以使用来自props的内容,创建一个名为toggleStatus的函数,并将其传递给onPress:

<TouchableOpacity onPress={toggleStatus}>
  <View
    style={[
      styles.circle,
      !props.status ? styles.completeCircle : styles.incompleteCircle,
    ]}
  ></View>
</TouchableOpacity>

toggleStatus的代码是:

const toggleStatus = () => {
  props.editHandler(props.todoKey, props.title, !props.status);
};

handleEdit将简化为:

const handleEdit = () => {
  props.editHandler(props.todoKey, text2, props.status);
  setEdit(false);
  console.log(props.status);
};

最后是TasksMain.js,这样就不会将存储中的内容替换为赋给useState的初始数组,确保saveTodoToUserDevicegetTodosFromUserDevice之后运行.为此,在TasksMain.js中添加下面的状态,并略微更改以下两个函数:

const [loading, setLoading] = React.useState(true);
const saveTodoToUserDevice = async (todos) => {
  if (loading) return;
  try {
    const stringifyTodos = JSON.stringify(todos);
    await AsyncStorage.setItem("todos", stringifyTodos);
  } catch (error) {
    console.log(error);
  }
};
const getTodosFromUserDevice = async () => {
  try {
    const todos = await AsyncStorage.getItem("todos");
    if (todos != null) {
      setTodos(JSON.parse(todos));
      console.log("loaded successfully");
    }
  } catch (error) {
    console.log(error);
  } finally {
    setLoading(false);
  }
};

Javascript相关问答推荐

如何在alpinejs中显示dev中x-for的元素

Angular material 表多个标题行映射

我在这个黑暗模式按钮上做错了什么?

使用i18next在React中不重新加载翻译动态数据的问题

数字时钟在JavaScript中不动态更新

使用Java脚本根据按下的按钮更改S文本

如何在 cypress 中使用静态嵌套循环

为什么Mutations 观察器用微任务队列而不是macrotask队列处理?

Reaction Native中的范围滑块

将核心模块导入另一个组件模块时存在多个主题

使用Google API无法进行Web抓取

material UI按钮组样式props 不反射

映射类型定义,其中值对应于键

在数组中查找重叠对象并仅返回那些重叠对象

同一类的所有div';S的模式窗口

如何使用Astro优化大图像?

FireBase FiRestore安全规则-嵌套对象的MapDiff

使用可配置项目创建网格

用Reaction-RT-Chart创建实时条形图

如何处理不带参数的redux thunk payloadCreator回调函数?