【问题标题】:React State is not updated with socket.io反应状态没有用 socket.io 更新
【发布时间】:2020-12-01 20:32:33
【问题描述】:

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

片段

  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], pivotType, 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();
    };
  }, []);

【问题讨论】:

    标签: reactjs react-hooks use-effect


    【解决方案1】:

    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], pivotType, rateOver: 
      rateOver, rateUnder:rateUnder, rateEqual:rateEqual};
            setLeagues(old_leagues);
          }
        }
      } 
    

    【讨论】:

    • 我之前也尝试过,但 LeaguesIsLoaded 从未设置为 true。
    猜你喜欢
    • 2020-07-22
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多