简体   繁体   中英

useState not triggers rerendering in websocket callback handler

Using web socket( @aspnet/signalr ) it works fine(in component callback is receiving the message)fine, I am able to receive and trigger callback in component(connection.on("UpdateProgress"... ) inside this callback its increment counter which is state variable( numberOfFailed ).. it triggers rendering only once, I set debugger and see numberOfFailed is always 0.

What's wrong here? why calling setNumberOfFailed doesn't change the value of numberOfFailed .

here is the code;

const [numberOfFailed, setNumberOfFailed] = useState(0);
const [connection, setConnection] = useState(null);

useEffect(() => {
  const newConnection = new HubConnectionBuilder()
    .withUrl(`${config.API_BASE_URL}update-progress`, {
      transport: HttpTransportType.WebSockets,
      accessTokenFactory: () => {
        return `${localStorage.token}`;
      },
    })
    .build();
  setConnection(newConnection);
}, []);

useEffect(() => {
  const fetchData = async () => {
    if (connection) {
      try {
        await connection.start();
        connection.onclose((error) => {
          console.info('Connection Closed:', error);
        });
        if (connection.state === HubConnectionState.Connected) {
          connection.on('UpdateProgress', (message) => {
            debugger;
            if (message.count) {
              setTitleText(`Bildirim Gonderim Başladı, Toplam Alıcı Sayısı:${message.count}`);
            } else if (message.status == 1) {
              let _t = numberOfFailed + 1;
              setNumberOfFailed(_t);
            }
            console.info('message', message);
          });
        }
      } catch (err) {
        console.log(err);
      }
    }
  };
  fetchData();
}, [connection]);

It was because react not trace the updated of variables which not explicitly defined in DependencyList. The best solution for this change the way..

This is how I solve this problem;

The main idea is using useReducer hook to update variables and use them in render.

const [connection, setConnection] = useState(null);
  const [counts, dispatch] = useReducer(BaskentMobilReducer, INITIAL_VALUE);

  useEffect(() => {
    const newConnection = new HubConnectionBuilder()
      .withUrl(`${config.API_BASE_URL}update-progress`, {
        transport: HttpTransportType.WebSockets,
        accessTokenFactory: () => {
          return `${localStorage.token}`;
        },
      })
      .build();
    setConnection(newConnection);
  }, []);

  useEffect(() => {
    const fetchData = async () => {
      if (connection) {
        try {
          await connection.start();
          connection.onclose((error) => {
            console.info("Connection Closed:", error);
          });
          if (connection.state === HubConnectionState.Connected) {
            connection.on("UpdateProgress", (message) => {
              if (message.count) {
                setTotalCount(message.count);
                setTitleText(
                  `Bildirim Gonderim Başladı, Toplam Alıcı Sayısı:${message.count}`
                );
              } else if (message.status == 0) {
                debugger;
                dispatch({
                  type: "UPDATE_COUNTS_SUCCESS",
                });
                console.log("counts", counts);
              } else if (message.status == 1) {
                debugger;
                dispatch({
                  type: "UPDATE_COUNTS_FAIL",
                });
                console.log("counts", counts);
              }
              console.info("message", message);
            });
          }
        } catch (err) {
          console.log(err);
        }
      }
    };
    fetchData();
  }, [connection]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM