useEffect用来监听组件间通信——订阅发布拿不到数据

1.在做这个图书订阅管理系统时,遇到一个这样的业务逻辑:

 

 

 

 

就是这样的逻辑:: 点击设置---》红色框里选择书籍---》点击提交按钮--》轮播图展示

也就是实现:在蓝色框第一次挂载时订阅也就是‘/admin’页面(图左),点击设置按钮,显示下面的红色框组件,在红色框组件选择要轮播的数据,点击提交按钮,在获取所选的全部数据后,进行发布(图右),并跳转到admin页面。

2.订阅采用useEffert监听,关于useEffert(https://www.jb51.net/article/258465.htm),简要介绍一下

useEffert(第一参数,第二参数),第一参数是一个逻辑处理函数()=>{这里面写数据处理逻辑},也称副效应函数,且允许返回一个函数在组件卸载时执行,多用来清除定时器、计时器、订阅

第二参数为第一参数提供依赖项,分为3种情况:啥也不写,useEffect()每次渲染都执行;[],第一次渲染的时候执行一次就不会再执行;[变量],当变量发生变化的时候执行

这是订阅的代码,没有啥问题,页面挂载的时候,订阅,卸载的时候取消订阅(这是useEffert的取消副作用)

const [imgs, setImglist] = useState([{ id: '001', name: "示例1", author: '示例1', publisher: '示例1', img: '' }]);
    useEffect(() => {
        let token = PubSub.subscribe('imgs', (msg, data) => {
            console.log(msg, data)
            setImglist(data)
        })
        console.log(token)
        return () => { console.log(token); PubSub.unsubscribe(token); }
    }, [imgs])

这是发布的代码,单击按钮时发布

  const toRatotionChart = ()=>{
    console.log(imgList)
    PubSub.publish('imgs',imgList);
    // navigate('/admin')
  }

我遇到的情况是,当加入return () => { console.log(token); PubSub.unsubscribe(token); }时,代码就不会进入到订阅的第一参数,导致获取不到数据。去掉,又会产生很多的订阅,逻辑上就是不能去掉的

解决办法,找了很久,通过不断地新测试,发现useEffect的使用,在AB组件通信时,A订阅,B发布,当B跳向A所在的页面时,A不会刷新的情况下,上述合理的代码才会正常让A拿到B发布的数据,也就是说当useEffect在A中监测B发布数据的变化时,A组件必须一直在,订阅的时候在页面上,B跳向他的时候也必须在页面上,让A组件自身与B组件出现的区域在同一页面上成同级关系,这样A不会刷新,之前对应产生的订阅Id就对应上了。

以上图为例子,蓝色框代表A,红色框代表B,如果这个红色框B在新的页面,A通过上面的代码是拿不到数据的,因为这个时候,红色框组件点击提交后要跳转到蓝色框A组件,A被重新渲染了,又重新订阅了一次,而每一次订阅应该是不同的,A第一次给的是uid0,但是当接受的时候A已经变成uid1了,它自然拿不到uid0的数据

 

这是针对这种现象的个人理解,效果有效,如果届时不对,麻烦指正,感谢




posted @ 2022-08-21 21:37  乔十六  阅读(137)  评论(0编辑  收藏  举报