react hooks踩坑记..

前言:

react hooks是react 16.7版本后出来的,算是一个比较新的东西,在最开始用的时候,个人用的不是很习惯,会有一些排斥,但是随着react社区中对hooks风评越来越好,我也在最近的1年多时间强制自己使用这个新特性,不用不知道,一用后面真的就放不下了.

发现坑:

今天在写websocket的时候发现一个问题

虽然执行了setData([])  但是在下面的initWS中的onmessage方法,依然引用了之前的老数据源,这里也没有办法给data添加副作用…

复现问题:

import React, {useEffect, useState} from 'react';
import { Button } from 'antd';

let i = 0;
export default () => {
  const [data,setData] = useState<number[]>([]);

  useEffect(()=>{
    console.log(data) // 添加副作用后 这里的data便是空数组了
  },[data])
  return (
    <div className="indexlayout-main-conent">
      {
        data.map(item =>{
          return (
            <div>{item}</div>
          )
        })
      }
      <Button onClick={()=>{
        i++;
        data.push(i);
        setData([...data])
      }}>添加一个...</Button>
      <Button onClick={()=>{
        console.log(data);
        setData([]);
        setTimeout(()=>{
          console.log(data); // 此处引用的data依然还是老的data
        },2000)
      }}>清空</Button>
    </div>
  );
};

以上可以复现我的问题,然而对于我的代码无法使用副作用来保证数据源是最新的,websocket里onmessage一直都有引用 data的数据,也一直引用着老数据源,无法释放,

于是在重置的时候只能把websocket关了再重启,以保证数据源是最新的.

修改后的代码:

const handleClearLog = () => {
  lockReconnect = true;
  data = []; // 这里必须先重置了 在setTimeout的域中是无法拿到空的data的
  websocket.close();
  clearInterval(websocketTime);
  setData([]);
  setTimeout(() => {
    initWS(); // 重新连接websocket
    websocketTime = setInterval(() => {
      if (websocket.readyState !== 1) {
        initWS()
      }
    }, 5000)
  }, 1000)
}

这样便可以了…

 

总结: 虽然是小问题 但是还是花了一些时间去排查,之前以为hooks与setState一样,可以在setTimeout与setInterval里拿到更新后的值,但是经历这次实践,发现并没想像的那么好.

 

 

 

 

 

 

Author: kaykie

发表评论

邮箱地址不会被公开。