在全局上下文中使用XState的React Native会导致整个应用重新加载

cpjpxq1n  于 2023-08-07  发布在  React
关注(0)|答案(1)|浏览(140)

我有一个React Native Expo应用程序,我使用XState来保持一个全局状态机,该状态机通过Context API传递到组件树中。
js:(仅示出相关部分-例如smSend函数在上下文中传递。

const GlobalXStateMachineContext = createContext({});
 
//Here stateDef and actionDef are state machine and actions
const stateMachine = createMachine(stateDef, actionDef);

export default function App() {

  console.log("APP INVOKED!!");

  const [smState, smSend] = useMachine(stateMachine);
  return (
    <Provider store={store}>
      <GlobalXStateMachineContext.Provider value={{ smSend }}>
        <NavigationContainer>
          <RootScreen />
        </NavigationContainer>
      </GlobalXStateMachineContext.Provider>
    </Provider>
  );
}
export { GlobalXStateMachineContext };

字符串
然后从组件树的深处,我从上下文获取smSend并调用它。
请注意,一切都在按预期工作。但是每当从组件树中的任何地方调用smSend()时,App()就会被调用,导致整个树的完全重新加载!
请注意,每次像这样调用smSend时,都会调用console.log(“APPINVOKED”)。
NestedFunction.js(同样仅限相关代码)

import { GlobalXStateMachineContext } from './App';

const NestedFunction = () => {
  const smSend = useContext(GlobalXStateMachineContext).smSend;
  ....
  smSend({ payload });
}


我不确定这是Context API或XState的预期行为,还是使用这两者的怪癖。这会导致性能下降,并可能导致难以发现的bug。
是否有任何方法可以避免应用程序的完全重新加载?

wljmcqd8

wljmcqd81#

尝试在React.memo中 Package 您的组件,例如RootScreen,这将防止这些组件重新渲染,除非需要。React memo docs
FYI React.memo不应该 Package 那些旨在重新呈现一堆的组件。
另外,如果你在一个钩子组件中返回内联组件,那么这些内联组件应该被移除或者用React.useMemo钩子记住。

相关问题