首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >保存多项时,AsyncStorage无法正常工作

保存多项时,AsyncStorage无法正常工作
EN

Stack Overflow用户
提问于 2020-07-11 21:19:54
回答 1查看 177关注 0票数 0

我有一个主屏幕,您可以看到以卡片形式显示的多个项目--您可以通过按下它来访问一个项目以查看其详细信息;在细节屏幕上,我添加了一个书签选项,该选项使用异步存储保存项目,您还可以在另一个名为savedItems屏幕的屏幕上检查保存的项目。

问题是:

  • 当我对一个项目做书签时,它会被正确保存,我可以在savedItems屏幕上找到它,但有时我必须重新加载该项目的应用程序才能显示在savedItems屏幕上,这是为什么?

  • ,如果我预订了多个项目,它们都会被保存(在console.log上),但是由于某种原因,只会出现最后一个项目,我从没有得到超过一个显示在SavedItems屏幕

上的项目。

Bellow是用于预订标记的代码片段(保存在其详细信息屏幕上的项目)。

Details.js

代码语言:javascript
复制
const DetailScreen = (props) => {
  const [saved, setSaved] = useState([]);
  const [items, setItems] = useState(props.route.params);
  const onSave = (item) => {
    const newItems = [...saved, item];

    setSaved(newItems);

    const items = JSON.stringify(newItems);

    SaveItem("saved", items).then((res) => {
      console.log("saved", res);
    });
  };

  const goToDetails = () => {
    setSaved([]);
    props.navigation.navigate("SaveScreen");
  };
  const { width, height } = Dimensions.get("window");
  const { data } = props.route.params; // this returns the data from each article

  //ReadItem("saved").then((res) => console.log(res));
  return (
  <TouchableOpacity
...
                onPress={() => {
                  onSave(data);
                }}
              >
                <MaterialCommunityIcons
                  name="bookmark"
                  size={35}
                  color={colors.shade2}
                />
              </TouchableOpacity>
)

SaveScreen.js

代码语言:javascript
复制
export default class Details extends Component {
  
  state = {
    saved: [],
  };

  removeItem = () => {
    DeleteItem("saved")
      .then((res) => {
        this.setState({
          saved: [],
        });
        console.log(res);
      })
      .catch((e) => console.log(e));
  };

  componentDidMount = () => {
    ReadItem("saved")
      .then((res) => {
        if (res) {
          const saved = JSON.parse(res);
          this.setState({
            saved: saved,
          });
        }
      })
      .catch((e) => console.warn(e));
  };

  render() {
    return (
      <View style={styles.container}>
        <FlatList
          keyExtractor={(item, index) => index.toString()}
          data={this.state.saved}
          renderItem={({ item }) => {
            return (
              <TouchableScale
                activeScale={0.9}
                tension={50}
                friction={7}
                useNativeDriver
                onPress={() =>
                  this.props.navigation.navigate("DetailScreen", { data: item })
                }
              >
                <Card item={item} />
              </TouchableScale>
            );
          }}
        />

        {this.state.saved.length > 0 && (
          <TouchableOpacity onPress={this.removeItem} style={styles.button}>
            <Text style={styles.save}>Remove Key</Text>
          </TouchableOpacity>
        )}
      </View>
    );
  }
}

用于使用异步存储保存数据的代码。

Dbhelper.js

代码语言:javascript
复制
import { AsyncStorage } from "react-native";

export const SaveItem = async (key, value) => {
  try {
    await AsyncStorage.setItem(key, value);
    console.log("saved");
  } catch (e) {
    console.log(e);
  }
};

export const ReadItem = async (key) => {
  try {
    var result = await AsyncStorage.getItem(key);
    return result;
  } catch (e) {
    return e;
  }
};

export function MultiRead(key, onResponse, onFailure) {
  try {
    AsyncStorage.multiGet(key).then((values) => {
      let responseMap = new Map();
      values.map((result, i, data) => {
        let key = data[i][0];
        let value = data[i][1];
        responseMap.set(key, value);
      });
      onResponse(responseMap);
    });
  } catch (error) {
    onFailure(error);
  }
}

export async function DeleteItem(key) {
  try {
    await AsyncStorage.removeItem(key);
    return true;
  } catch (exception) {
    return false;
  }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-11 21:57:23

如果我预订了多个项目,它们都会被保存(在console.log上),但是由于某种原因,只会出现最后一个条目,我在SavedItems屏幕上永远不会得到更多的条目。

我认为问题在于,当您保存新项目时,您会删除旧项目。在挂载DetailScreen时,您必须读取旧项目。或者可以在onSave方法中读取项。更安全。这取决于您的应用程序架构。

代码语言:javascript
复制
const DetailScreen = (props) => {
  const [items, setItems] = useState(props.route.params);
  
  const onSave = (item) => {
    let saved = [];

    ReadItem("saved")
      .then((res) => {
        if (res) {
          saved = JSON.parse(res);
        }

        const newItems = [...saved, item];
        const items = JSON.stringify(newItems);

        SaveItem("saved", items).then((res) => {
          console.log("saved", res);
        });
      })
      .catch((e) => console.warn(e));
  };


  const goToDetails = () => {
    setSaved([]);
    props.navigation.navigate("SaveScreen");
  };
  const { width, height } = Dimensions.get("window");
  const { data } = props.route.params; // this returns the data from each article

  //ReadItem("saved").then((res) => console.log(res));
  return (
  <TouchableOpacity
...
                onPress={() => {
                  onSave(data);
                }}
              >
                <MaterialCommunityIcons
                  name="bookmark"
                  size={35}
                  color={colors.shade2}
                />
              </TouchableOpacity>
)

--当我将一项书签正确保存时,我可以转到savedItems屏幕并在那里找到它,但有时我必须重新加载该项目的应用程序才能显示在savedItems屏幕上,这是为什么?

我只知道为什么会发生这种事。在某些情况下,您不会卸载SaveScreen。返回到SaveScreen时,不调用componentDidMount。只需尝试将console.log添加到componentDidMount,当您重现此行为时,如果错过了console.log,就意味着SaveScreen没有卸载

要处理所有案件,您可以尝试这样做:

代码语言:javascript
复制
export default class Details extends Component {
  
  state = {
    saved: [],
  };

  removeItem = () => {
    DeleteItem("saved")
      .then((res) => {
        this.setState({
          saved: [],
        });
        console.log(res);
      })
      .catch((e) => console.log(e));
  };

  componentDidMount = () => {
    this.readItems();
    this.unsubscribe = navigation.addListener('focus', this.readItems);
  };

  componentWillUnmount() {
    this.unsubscribe();
  }

  readItems = () => {
    ReadItem("saved")
      .then((res) => {
        if (res) {
          const saved = JSON.parse(res);
          this.setState({
            saved: saved,
          });
        }
      })
      .catch((e) => console.warn(e));
  }

  render() { ... }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62854712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档