React State未使用socket.io

问题描述

首次加载页面时,我需要获取所有信息,这就是为什么我要调用获取请求并将结果设置为State的原因[singleCall函数完成该工作] 与此同时,我正在使用socket.io连接websocket并监听两个事件(odds_insert_one_two,odds_update_one_two),当我收到通知事件时,我必须 检查以前的状态并修改一些内容并更新状态,而无需再次调用获取请求。但是该先前状态仍为[](初始)。 如何获取更新状态?

摘要

  const [leagues,setLeagues] = useState([]);
  
  const singleCall = (page = 1,params=null) => {

    let path = `${apiPath.getLeaguesMatches}`;
    Helper.getData({path,page,params,session}).then(response => {
      if(response) {
        setLeagues(response.results);
      } else {
        toast("Something went wrong,please try again");
      }
    }).catch(err => {
      console.log(err); 
    })
  };

  const updateData = (record) => {

    for(const data of record) {
      var {matchId,pivotType,rateOver,rateUnder,rateEqual} = data;
      const old_leagues = [...leagues]; // [] becuase of initial state value,that is not updated
      const obj_index = old_leagues.findIndex(x => x.match_id == matchId);
      if(obj_index > -1) {
        old_leagues[obj_index] = { ...old_leagues[obj_index],rateOver: rateOver,rateUnder:rateUnder,rateEqual:rateEqual};
        setLeagues(old_leagues);
      }
    }
  } 

  useEffect(() => {

    singleCall();

    var socket = io.connect('http://localhost:3001',{transports: ['websocket']});

    socket.on('connect',() => {
        console.log('socket connected:',socket.connected);
    });
    socket.on('odds_insert_one_two',function (record) {
      updateData(record);
    });

    socket.on('odds_update_one_two',function (record) {
      updateData(record);
    });

    socket.emit('get_odds_one_two');

    socket.on('disconnect',function () {
      console.log('socket disconnected,reconnecting...');
      socket.emit('get_odds_one_two');
    });

    return () => {
        console.log('websocket unmounting!!!!!');
        socket.off();
        socket.disconnect();
    };
  },[]);

解决方法

useEffect挂钩是使用空的依赖项数组创建的,因此在初始化阶段仅被调用一次。因此,如果league状态被更新,则其值将在updateData()函数中永远不可见。

您可以做的是将league的值分配给ref,并创建一个新的hook,该值每次都会更新。

const leaguesRef = React.useRef(leagues);

React.useEffect(() => {
  leaguesRef.current = leagues;
});

leagues更新为leaguesRef.current

  const updateData = (record) => {
    for(const data of record) {
      var {matchId,pivotType,rateOver,rateUnder,rateEqual} = data;
      const old_leagues = [...leaguesRef.current]; // [] becuase of initial state value,that is not updated
      const obj_index = old_leagues.findIndex(x => x.match_id == matchId);
      if(obj_index > -1) {
        old_leagues[obj_index] = { ...old_leagues[obj_index],rateOver: 
  rateOver,rateUnder:rateUnder,rateEqual:rateEqual};
        setLeagues(old_leagues);
      }
    }
  } 

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...