繁体   English   中英

React - 设置 state 在回调 function 中没有改变

[英]React - set state doesn't change in callback function

我无法在refreshWarehouseCallback function 中读取当前 state。为什么? 我的组件:

export function Schedules({ tsmService, push, pubsub }: Props) {
    const [myState, setMyState] = useState<any>(initialState);

 useEffect(() => {
        service
            .getWarehouses()
            .then((warehouses) =>
                getCurrentWarehouseData(warehouses) // inside of this function I can without problems set myState
            )
            .catch(() => catchError());

        const pushToken = push.subscribe('public/ttt/#');
        const pubSubToken = pubsub.subscribe(
            'push:ttt.*',
            refreshWarehouseCallback // HERE IS PROBLEM, when I try to read current state from this function I get old data, state changed in other functions cannot be read in thi function
        );

        return () => {
            pubsub.unsubscribe(pubSubToken);
            push.unsubscribe(pushToken);
        };
    }, []);

...

function refreshWarehouseCallback(eventName: string, content: any) {
      const {warehouseId} = myState; // undefined!!!
      case pushEvents.ramp.updated: {
}
}


return (
        <Views
            warehouses={myState.warehouses}
            allRamps={myState.allRamps}
            currentWarehouse={myState.currentWarehouse}
            pending={myState.pending}
            error={myState.error}
        />

我必须另外使用useRef来存储当前的 state 才能重新渲染整个组件。

我的问题是 - 没有useRef是否还有其他解决方案? 问题出在哪儿? Calback function 不适用于useState挂钩?

您的发布/订阅模式不会继承 React 的状态。 每当触发subscribe ,并且您的回调 function 已初始化时,该回调将不会从myState获取任何新值。

为了能够使用 React 的状态,您可以将refreshWarehouseCallback包装到另一个 function 中,如下所示

//`my state` is passed into the first function (the function wrapper)
//the inner function is your original function
const refreshWarehouseCallback =
  (myState) => (eventName: string, content: any) => {
    const { warehouseId } = myState;
    //your other logic
  };

然后您可以添加另一个useEffect以在 state 次更改后更新subscribe (在本例中, myState更新)

 //a new state to store the updated pub/sub after every clean-up
const [pubSubToken, setPubSubToken] = useState();

useEffect(() => {
  //clean up when your state updates
  if (pubSubToken) {
    pubsub.unsubscribe(pubSubToken);
  }
  const updatedPubSubToken = pubsub.subscribe(
    "push:ttt.*",
    refreshWarehouseCallback(myState) //execute the function wrapper to pass `myState` down to your original callback function
  );

  //update new pub/sub token
  setPubSubToken(updatedPubSubToken);

  return () => {
    pubsub.unsubscribe(updatedPubSubToken);
  };

//add `myState` as a dependency
}, [myState]);

//you can combine this with your previous useEffect
useEffect(() => {
  const pushToken = push.subscribe("public/ttt/#");

  return () => {
    pubsub.unsubscribe(pushToken);
  };
}, []);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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