【问题标题】:React redux updates flatlist item but turns item into an ArrayReact redux 更新 flatlist 项目,但将项目转换为数组
【发布时间】:2019-09-08 23:38:29
【问题描述】:

我正在使用带有 react native 的 react redux,我有一个平面照片列表。当我单击“赞”按钮时,我只想更新平面列表中的一张照片。以下代码似乎有效,并且照片的状态已更新,但不知何故我的提要在更新后搞砸了。更新前this.props.feed[index]是单个对象,更新后this.props.feed[index]变成对象数组,我做错了什么?我的想法来自:https://stackoverflow.com/a/47651395/10906478

但是,循环遍历 flatlist 的所有项目以找到与传入的 photoId 匹配的项目似乎也非常低效。有没有更好的办法?

屏幕:

toggleLike = async(photoId, index) => {
    console.log("before: ", this.props.feed[index]);
    await this.props.toggleLike(photoId);
    console.log("after: ", this.props.feed[index]);
}

...

<FlatList
    data = {this.props.feed}
    keyExtractor = {(_, index) => index.toString()}
    renderItem = {({item, index}) => (
        <View key={index}>
            <TouchableOpacity onPress={()=> this.toggleLike(item.photoId, index)}>
                <Text>Button</Text>
            </TouchableOpacity>
        </View>
    )}
/>

动作

export const toggleLike = (photoId) => async(dispatch) => {
    dispatch({type: "UPDATE_ITEM", photoId: photoId})
}

减速器

export default (state = initialState, action) => {
    switch(action.type) {
        case "UPDATE_ITEM":
            return {...state, feed: [state.feed.map((item,_) => {
                if (item.photoId === action.photoId) {
                   return { ...item, liked: !item.liked };
                }
                return { ...item };
            })]};

        // other cases

【问题讨论】:

    标签: reactjs react-native redux react-redux react-native-flatlist


    【解决方案1】:

    你在一个数组中调用map,它返回一个嵌套数组:

    return {...state, feed: /* Here ->*/[state.feed.map((item,_) => {
        if (item.photoId === action.photoId) {
            return { ...item, liked: !item.liked };
        }
        return { ...item };
    })]};
    

    应该这样做:

    return {
      ...state, // Current state
      feed: state.feed.map((item, _) => { // map returns a new array
        if (item.photoId === action.photoId) {
          item.liked = !item.liked;
        }
        return item;
      })
    }
    

    【讨论】:

    • 在=&gt; { 上获取属性分配预期错误
    • 哎呀,添加了括号。不过,这个想法的要点就在那里。
    • 谢谢!这实际上是实现这一目标的最有效方法吗?因为循环遍历列表的所有项目以查找匹配的 ID 似乎有点过头了?
    • 可能有更有效的方法,但除非你有一个荒谬的长数组,否则我不会太担心。
    【解决方案2】:

    对于作为数组的提要,请仔细查看您的代码。您将看到您已将 feed 的值包含在方括号中并在数组上运行映射。所以 feed 是一个数组,map 也是一个数组。这就是为什么在 state.feed 的每个索引点都有一个对象数组的原因。我通常建议你去掉周围的方括号,让你的地图创建数组。

    不过,这实际上并不是问题的根本原因,还有更彻底的解决方案。

    如果需要在不打乱数组顺序的情况下找到匹配的ID并更新“liked”值,请尝试在数组上使用findIndex而不是map。找到您的项目所在的索引并仅更新该值。如果它抱怨直接改变 Redux 存储值,您可能需要克隆数组和内部对象。

    祝你好运!

    【讨论】:

    • 不会 findIndex 必须循环遍历列表吗?所以在性能方面它与创建地图一样吗?不确定我是否完全理解你的答案。能不能写成代码
    猜你喜欢
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    相关资源
    最近更新 更多