You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native基于AsyncStorage实现电影WatchList收藏功能

基于AsyncStorage实现待观看观影清单功能

你已经在代码里引入了@react-native-async-storage/async-storage,不需要额外安装依赖,直接按以下步骤修改代码即可:


1. 补充状态定义

找到组件内的useState声明块,新增收藏状态标记:

const [loading, setLoading] = useState(true);
const [details, setDetails] = useState();
const [favourites, setFavourites] = useState([]);
// 新增:标记当前电影是否已加入清单
const [isFavourite, setIsFavourite] = useState(false);

顺便提一句:你原有代码里拉取视频的接口路径模板字符串写法有误,/movie/${props.route.params.movieId/videos} 要改成 /movie/${props.route.params.movieId}/videos,否则视频接口会请求失败。


2. 添加本地存储操作方法

在getGenre方法同级位置,添加以下逻辑:固定存储key、读取本地清单、切换收藏状态

// 本地存储固定key,避免读写时key不一致
const WATCHLIST_KEY = '@movie_watchlist';

// 页面加载时读取本地已存的观影清单
const loadLocalWatchlist = async () => {
  try {
    const storedData = await AsyncStorage.getItem(WATCHLIST_KEY);
    if (storedData) {
      const list = JSON.parse(storedData);
      setFavourites(list);
      // 判断当前电影是否已在清单中
      const currentMovieInList = list.some(item => item.id === props.route.params.movieId);
      setIsFavourite(currentMovieInList);
    }
  } catch (err) {
    console.log('读取本地清单失败', err);
  }
};

// 点击按钮时切换收藏状态
const toggleWatchlist = async () => {
  try {
    let newList = [];
    if (isFavourite) {
      // 已在清单中:移除当前电影
      newList = favourites.filter(item => item.id !== details.id);
    } else {
      // 不在清单中:存入当前电影的必要展示字段,不要存全量详情浪费存储空间
      const movieInfo = {
        id: details.id,
        title: details.title,
        poster_path: details.poster_path,
        vote_average: details.vote_average,
        release_date: details.release_date,
        overview: details.overview
      };
      newList = [...favourites, movieInfo];
    }
    // 先更新页面状态
    setFavourites(newList);
    setIsFavourite(!isFavourite);
    // 同步持久化到本地存储
    await AsyncStorage.setItem(WATCHLIST_KEY, JSON.stringify(newList));
  } catch (err) {
    console.log('更新清单失败', err);
  }
};

3. 页面加载时触发本地数据读取

修改你第一个拉取电影详情的useEffect,在详情数据加载完成后调用读取本地清单的方法:

useEffect(() => {
  const getDetails = async () => {
    const data = await GET(`/movie/${props.route.params.movieId}`);
    setDetails(data);
    setLoading(false);
    // 详情加载完成后读本地收藏数据
    loadLocalWatchlist();
  };
  getDetails();
}, []);

4. 绑定收藏按钮事件

找到你现在写在返回按钮旁边、用nolicked.png图标的TouchableOpacity组件,替换成以下代码,绑定点击事件、根据状态切换图标:

<TouchableOpacity  
  onPress={toggleWatchlist}
  style={{  marginLeft:20, marginTop: 20, marginBottom:20}} 
>
  <Image
    // 这里替换成你自己项目里的已收藏图标路径即可
    source={isFavourite ? require("../../assets/icons/liked.png") : require("../../assets/icons/nolicked.png")}
    style={{ width:256/5.7 , height: 252/5.7 }} 
  />
</TouchableOpacity>

观影清单页读取数据

单独做观影计划列表页时,只需要在对应页面的useEffect里用同样的key调用AsyncStorage.getItem(WATCHLIST_KEY),拿到数据JSON.parse之后,用FlatList渲染即可,和你现有热门电影列表的渲染逻辑完全一致。

注意:AsyncStorage仅支持存储字符串类型,所以存数组/对象时必须先用JSON.stringify转成字符串,读取后再用JSON.parse转回结构化数据,否则会报错。对于你当前的入门项目,AsyncStorage完全够用,不需要引入更重的数据库方案。

内容的提问来源于stack exchange,提问作者SO KP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 05:15:55