gpt4 book ai didi

reactjs - Recoil JS - 摆脱重新渲染我的应用程序的悬念

转载 作者:行者123 更新时间:2023-12-04 04:05:18 26 4
gpt4 key购买 nike

我正在我目前正在构建的 React 框架中试验 Recoil。在我的用例中,应用程序将根据用户事件生成一个操作对象,然后将其发送到服务器,从服务器获取应用程序状态。

Action 存储在反冲 atom 中。我正在使用接受操作并从服务器获取状态的反冲 selectorFamily。以下是我实际在做什么的简单示例(代码在 typescript 中):

export const MyActionAtom = atom<MyAction|undefined>({
key: "MyActionAtom",
default: undefined
});

const MyStateSelectorFamily = selectorFamily({
key: 'MyStateSelectorFamily',
get: (action: MyAction|undefined) => async ({get}) => {
if (action) {
return await getStateFromServer(action);
}
return SomeFallbackState;
}
});

const MyStateSelector = selector({
key: 'MyStateSelector ',
get: ({get}) => {
return get(MyStateSelectorFamily(get(MyActionAtom)));
}
});


function App() {
const appState = useRecoilValue(MyStateSelector);
return (
<RecoilRoot>
<React.Suspense fallback={<div>Loading...</div>}>
<MyApp state={appState} />
</React.Suspense>
</RecoilRoot>
);
}

这里,MyApp 是一个 React 组件,它将根据 appState 呈现应用程序的整个 View 树。

现在,从 MyApp 的直接或间接子组件中,可以触发另一个操作:

const setMyAction = useSetRecoilState(MyActionAtom);
setMyAction(...);

setMyAction 的结果与我初始化应用程序时使用的初始状态相比,值略有偏差。因此,我只想重新渲染依赖于更改状态的组件。

但是,我的整个 View 树都得到了更新。我怀疑的原因是 React.Suspense 正在用回退替换 dom,直到返回操作的响应(注意 MyStateSelectorFamily 是异步的,因为状态返回为一个 promise )。

在一个更像 redux 的世界中,我会在 promise 得到解决后触发我的请求并发送状态更改(并且我打算以不同于 React.Suspense 的方式处理加载状态我)。

有没有办法阻止我的应用程序重新呈现?我已经看到使用 recoil Loadables 以避免 React.Suspense 的示例,但是当可加载项处于 loading< 时,我正在努力获取旧的应用程序状态 状态。


更新

随着我的进一步实验,我能够通过调度方法使其模仿 reducer 方法:

  1. 我摆脱了 Action 原子,并将 MyStateSelectorFamily 更改为原子本身:

    const MyStateAtom = atom({
    key: 'MyStateAtom ',
    default: SomeFallbackState
    });
  2. 我用自定义 Hook 替换了组件中的 setMyAction(...); 部分:

    // in some dedicated ts file:
    export const useAction = () => {
    const dispatch = useSetRecoilState(MyStateAtom);
    return useCallback(async (action: MyAction) => {
    await getStateFromServer(action).then(dispatch);
    }, [dispatch]);
    };
  3. 我在组件中使用钩子(Hook):

     export const SomeComponent = (props: SomeProps) => {
    const dispatchAction = useAction();
    // other logic
    const action: MyAction = ... // create the appropriate action
    dispatchAction(action);

    return (...);
    };

好吧,这似乎按照我的意愿工作,并且更接近我以前使用 redux 的代码库,所以我非常喜欢它而不是以前的 selectorFamily 方法。但是,我经常在控制台中看到 react 警告:

 Warning: Cannot update a component (`Batcher`) while rendering a 
different component (`SomeComponent`) ....

我的应用程序是一个 SPA 应用程序,并且在初始加载时打印警告。然后它可以正常工作,没有任何可观察到的问题。我想知道我是否可以修复警告的原因——这个 Batcher 似乎是一个反冲的东西,我想我没有做正确的事情来打破它。

最佳答案

讨论弹出警告的原因here .这基本上是 Recoil 内部的逻辑流程错误,将在下一个版本中修复。目前您无能为力,但它只会在开发模式下弹出,而在生产模式下警告会被忽略。

关于reactjs - Recoil JS - 摆脱重新渲染我的应用程序的悬念,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62601155/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com