收藏
回答

小程序关于用户点击“收藏”与“取消收藏”的问题?引用自定义组件时数据如何不出错?

做了一个关于商家动态列表的自定义组件,同时有三四个页面(商家主页、商家动态、我的收藏)引用,怎么让每个页面的“是否收藏”数据不出错?

目前,

商家主页 问题:(简单来说就是 表示“是否收藏”的数据不同步,状态与实际相反)

进入页面时全部显示“未收藏”状态(不管是否收藏)

点击第一下“收藏”按钮,按钮状态没有变化(查看后台数据为已收藏),点击第二下按钮变为“已收藏”(后台数据为取消收藏)

商家动态 页面问题:

点击页面 所有动态列表状态为 “未收藏”(不管后台数据是否为 收藏)

保留delCb(id, collect) 则商家动态页面不能正常展示 收藏 与 取消收藏 功能

删除delCb(id, collect) 则功能正常,但刷新页面后,依旧变成“未收藏”状态(后台数据为 已收藏)

我的收藏 页面:(此页面的 是否收藏 状态正常显示)

保留delCb(id, collect) 则取消收藏时列表自动删除

删除delCb(id, collect) 则取消收藏后需手动刷新一下,列表才能消失


自定义组件代码:

import React, { memo, useCallback, useEffect, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import {
    View,
    Text,
    Image,
    showLoading,
    hideLoading,
    showToast,
    saveImageToPhotosAlbum,
    showModal,
    openSetting,
    getImageInfo,
    setClipboardData,
    redirectTo,
    navigateTo,
    ad
} from 'remax/wechat';
import request from '@/utils/request'
import { clearSearchBase64Url } from '@/actions/common'
import { connect } from 'react-redux';
import * as utils from '@/utils/common';

import styles from './index.css';
import classnames from 'classnames';

const SearchItem = memo(function (props) {
    const {
        dynamic: { dynamic_img, dynamic_title, nickname, user_id, id, head_img, date, img_url, cover_img, is_favorites },
        contactCb,
        delCb,
        clearSearchBase64Url,
        isBusiness,
        userInfo,
        adUnitId
    } = props;
    const dynamicArr = dynamic_img.split('|');
    const [collect, setCollect] = useState();

    useEffect(() => {
        setCollect(parseInt(is_favorites))
        // setCollect(is_favorites)
    }, [is_favorites])

    const addCollect = useCallback((e) => {
        e.stopPropagation();
        if (!userInfo) {
            navigateTo({
                url: '/packagePagesC/pages/sub/login/index'
            })
            return
        }
        request({
            url: '/dynamicFavorites',
            data: {
                dynamic_id: id
            },
            origin: true,
            method: 'post'
        }).then(res => {
            if (res.code === 0) {
                showToast({
                    title: collect ? '取消收藏' : '收藏成功',
                    icon: 'none'
                })
                delCb(id, collect)   //注意!!!!!!!不加这一行,“我的收藏”页面取消收藏时,不能自动删除列表,需要手动刷新;
//但是 加了这一行,开发者工具报错(如下图),且下一行代码不运行。
                setCollect(prev => prev === 0 ? 1 : 0);
                return;
            }
            throw new Error('操作失败')
        }).catch(e => {
            showToast({
                title: e,
                icon: 'none'
            })
        })
    }, [collect, userInfo])

    const saveMultPicToLocal = useCallback(async (e) => {
        e.stopPropagation()
        showLoading({
            title: '正在保存图片',
            mask: true
        })
        try {
            for (let img of dynamicArr) {
                await getImageInfo({
                    src: img
                }).then(ret => {
                    saveImageToPhotosAlbum({
                        filePath: ret.path,
                    })
                }).catch(e => {
                    console.log(e)
                })
            }
            hideLoading()
            showModal({
                title: '商品描述已复制,图片已保存,打开朋友圈手动发布即可'
            }).then(res => {
                if (res.confirm) {
                    setClipboardData({
                        data: dynamic_title
                    })
                }
            })
        } catch (e) {
            if (e.errMsg === 'saveImageToPhotosAlbum:fail auth deny') {
                showModal({
                    title: '请打开保存图片到相册的权限'
                }).then(res => {
                    if (res.confirm) {
                        openSetting().then(({ authSetting }) => {
                            if (authSetting['scope.writePhotosAlbum']) {
                                saveMultPicToLocal()
                            }
                        })
                    }
                })
            } else {
                showToast({
                    title: '保存失败',
                    icon: 'none'
                })
            }
        }
    }, [dynamic_title])

    const dynamiCls = classnames([styles.dynamic], {
        [styles.grey]: date === '置顶'
    })
    if (!id) {
        return (
            <ad unit-id={adUnitId} binderror={(err) => {
                console.log(err)
            }}></ad>
        )
    };
    return (
        <View className={dynamiCls} onTap={() => {
            clearSearchBase64Url()
            navigateTo({
                url: '/packagePagesC/pages/sub/detail/index?dynamicId=' + id
            })
        }}>
            <View className={styles.imgWrapper}>
                <Image src={cover_img || dynamicArr[0]} mode="aspectFill" />
                <Text>{dynamicArr.length}</Text>
            </View>
            <View className={styles.info}>
                {
                    !isBusiness &&
                    <View className={styles.infoHeader}>
                        <View className={styles.infoLeft} onTap={(e) => {
                            e.stopPropagation();
                            clearSearchBase64Url()
                            navigateTo({
                                url: '/packagePagesC/pages/sub/business/index?userId=' + user_id
                            })
                        }}>
                            <Image src={head_img} />
                            <Text>{nickname}</Text>
                        </View>
                        <Text onTap={(e) => {
                            e.stopPropagation();
                            contactCb({
                                ...props.dynamic,
                                userId: props.dynamic.user_id
                            })
                        }}>联系TA</Text>
                    </View>
                }
                <View className={styles.desc} >{dynamic_title}</View>
                {
                    isBusiness && <View className={styles.dynamicTime}>{date}</View>
                }
                <View className={styles.func}>
                    <View className={styles.funcLeft}>
                        <View onTap={saveMultPicToLocal}>
                            <Image src="http://dxshy.duxieshe.com/uploads/applet_img/download.png" />
                            <Text>下载</Text>
                        </View>
                        <View onTap={addCollect}>
                            <Image src={collect ? "http://dxshy.duxieshe.com/uploads/applet_img/collectActive.png" : "http://dxshy.duxieshe.com/uploads/applet_img/collect.png"} />
                            <Text>{collect ? '已收藏' : '收藏'}</Text>
                        </View>
                    </View>
                </View>
            </View>
        </View>
    )
})
SearchItem.propTypes = {
    dynamic: PropTypes.object.isRequired,
    contactCb: PropTypes.func.isRequired,
    delCb: PropTypes.func.isRequired
}
SearchItem.defaultProps = {
    contactCb: () => { },
    delCb: () => { },
}
const mapStateToProps = (state) => {
    const { userInfo } = state.common
    return {
        userInfo
    }
}
const mapDispatchToProps = (dispatch) => {
    return {
        clearSearchBase64Url: () => {
            dispatch(clearSearchBase64Url())
        }
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(SearchItem);


关于delCb(id, collect)的报错:



回答关注问题邀请回答
收藏

1 个回答

  • ⅴ
    2022-10-28

    怎么感觉似曾相识,后台collect返回了啥

    2022-10-28
    有用
    回复 5
    • 啵啵
      啵啵
      2022-10-28
      和之前的“关注”有点像,但是这个同一个自定义组件在不同的页面表现出来的又不一样了。
      2022-10-28
      回复
    • ⅴ
      2022-10-28回复啵啵
      delCb(id, collect) 这个是不是应该先判断collect再执行,只有取消收藏的时候执行。
      2022-10-28
      回复
    • 啵啵
      啵啵
      2022-10-28
      2022-10-28
      回复
    • 啵啵
      啵啵
      2022-10-28
      改成这样?商家动态页面 收藏的状态可以正常改变了,但是我的收藏 页面跟之前的结果一样,需要手动刷新删除列表
      2022-10-28
      回复
    • 啵啵
      啵啵
      2022-10-28回复啵啵
      点击收藏按钮的时候依旧会报错
      2022-10-28
      回复
登录 后发表内容