首页 > 解决方案 > useState 不会在 websocket 回调处理程序中触发重新渲染

问题描述

使用 web socket( @aspnet/signalr) 它工作正常(在组件回调中接收消息)很好,我能够在这个回调内部的组件(connection.on(“UpdateProgress”...)中接收和触发回调,它的增量计数器是状态变量(numberOfFailed)..它只触发一次渲染,我设置调试器,看到numberOfFailed总是0。

这里有什么问题?为什么调用setNumberOfFailed不会改变numberOfFailed.

这是代码;

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]);

标签: reactjsreact-hooks

解决方案


这是因为 react 不跟踪未在 DependencyList 中明确定义的变量的更新。改变这种方式的最佳解决方案..

这就是我解决这个问题的方法;

主要思想是使用 useReducer 挂钩来更新变量并在渲染中使用它们。

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]);

推荐阅读