ページリロードなしでルートを回復する
14749 ワード
最近、私はそれが反応ルータでバグのように思えた上で働いているアプリで面白いバグに遭遇しました.私は、それが本当にバグであるというわけではありませんでした、しかし、何かが反応ルータで実装されないままになったので、それが開発者の必要に応じて複数の方法で「固定」されることができるので.( the issue on github )
私たちの特定の問題は、我々は現在の反応ルートによってレンダリングされたリストの項目を更新していたサーバーコールの後にページリフレッシュをしたいということでした.リストは、より高いコンテクスト状態に格納されたいくつかのフィルタに基づいてロードされます.さらに、我々のアプリは、ルートが特定のサブセット内に応じてマウントされていることを意味する別のアプリケーションにロードされました.
最初にページリフレッシュをしなければならなかったコードは
ステップ1
私が考えていた最初の解決策は
それから、私は我々のスタンドアロンアプリケーションの中でちょうどうまく働いたハックを見つけました.
ステップ2
しかし、アプリケーションのルータがネストされたルートにマウントされたので
次のステップは、マイクロフロントアプリのインデックスルートにプッシュすることでした.
ステップ△3-溶液
現在、問題は、これがいつも正しく作動していないということです.どのように高速(または遅い)に応じて反応ルーターは、それがコンポーネントをマウントしないかをトリガする管理場所を更新!それで、2番目の歴史アップデートが遅れているならば、少しの反応はそれがそうであることを示します.
使用に苦労した後
余震
私が上記のコードスニペットを貼ったので、私は私のuserefreshフックAPIをさらに簡単にすることができると思い始めています.パラメータはありません: 方法について リファクタリングを行います.
ボーナス
ここではいくつかのユニットテスト私は
私たちの特定の問題は、我々は現在の反応ルートによってレンダリングされたリストの項目を更新していたサーバーコールの後にページリフレッシュをしたいということでした.リストは、より高いコンテクスト状態に格納されたいくつかのフィルタに基づいてロードされます.さらに、我々のアプリは、ルートが特定のサブセット内に応じてマウントされていることを意味する別のアプリケーションにロードされました.
最初にページリフレッシュをしなければならなかったコードは
handleItemUpdateSuccess() {
history.push('app/list');
}
ここで問題となるのは、反応がapp/list
国家では何も変わっていなかったからです.ステップ1
私が考えていた最初の解決策は
dispatch
the getList
アクションとリストコンポーネントの読み込み自体は、何もしないでください.これは正しい解決策であったかもしれませんが、私のリストコンポーネントに非常に特有のようでした.それから、私は我々のスタンドアロンアプリケーションの中でちょうどうまく働いたハックを見つけました.
handleItemUpdateSuccess() {
history.push('/');
history.replace(redirectPath);
}
ステップ2
しかし、アプリケーションのルータがネストされたルートにマウントされたので
history.push('/')
国連は、そこにロードされた反応アプリ全体をマウントします.これは、コンテキスト全体がワイプされることを意味します.次のステップは、マイクロフロントアプリのインデックスルートにプッシュすることでした.
history.push(MicroFrontendRoute.Index);
history.replace(redirectPath);
これは1つの問題を解決します.ステップ△3-溶液
現在、問題は、これがいつも正しく作動していないということです.どのように高速(または遅い)に応じて反応ルーターは、それがコンポーネントをマウントしないかをトリガする管理場所を更新!それで、2番目の歴史アップデートが遅れているならば、少しの反応はそれがそうであることを示します.
使用に苦労した後
setTimeout
JSメソッドと適切に行うことができるbeeingclearTimeout
同じ方法で、カスタムフックにすべてを抽出することにしました.# ../app/routes/useRefresh.ts
import { useEffect } from 'react';
import { MyAppRoute } from './MyAppRoute';
export default function useRefresh(history: any, path: string, resetRoute: string = MyAppRoute.Index) {
let handler: any;
const refresh = () => {
history.push(resetRoute);
handler = setTimeout(() => history.push(path), 10);
};
useEffect(() => {
return () => handler && clearTimeout(handler);
}, [handler]);
return refresh;
}
今、すべてのリフレッシュロジックが安全に独自のフックにカプセル化されているので、それをどのように使うのが簡単かを教えてください. const history = useHistory();
const refresh = useRefresh(history, redirectPath);
const handleSuccess = () => {
if (history.location.pathname === redirectPath) {
refresh();
} else {
history.push(redirectPath);
}
};
const handleErrors = () => {
...
余震
私が上記のコードスニペットを貼ったので、私は私のuserefreshフックAPIをさらに簡単にすることができると思い始めています.パラメータはありません:
useHistory
インサイドフック-第1パラメータダウンredirectPath
返されるより多くに合うようですrefresh
関数-- 2番目のパラメータもダウンします.ボーナス
ここではいくつかのユニットテスト私は
useRefresh
Jestとテストライブラリを使用してフック..import { renderHook, act } from '@testing-library/react-hooks';
import { createMemoryHistory } from 'history';
import useRefresh from '../../../../components/app/routes/useRefresh';
import { MyAppRoute } from '../../../../components/app/routes/MyAppRoute';
describe('useRefresh', () => {
const history = createMemoryHistory();
const subject = () => renderHook(() => useRefresh(history, MyAppRoute.List));
it('returns a function', () => {
const { result } = subject();
expect(typeof result.current).toBe('function');
});
it('redirect to the Index route and then back to the given path', async () => {
jest.useFakeTimers();
jest.spyOn(history, 'push');
const { result } = subject();
result.current();
expect(history.push).toHaveBeenCalledWith(MyAppRoute.Index);
act(() => {
jest.runAllTimers();
});
expect(history.push).toHaveBeenCalledWith(MyAppRoute.List);
expect(history.push).toHaveBeenCalledTimes(2);
});
it('clears the timeout', () => {
jest.useFakeTimers();
const { result, unmount } = subject();
result.current();
act(() => {
jest.runAllTimers();
});
unmount();
expect(clearTimeout).toHaveBeenCalledTimes(1);
});
});
あなたが反応ルータとルートをリフレッシュするより良い方法を知っているならばsetTimeout
:| コメントで知らせてくださいReference
この問題について(ページリロードなしでルートを回復する), 我々は、より多くの情報をここで見つけました https://dev.to/zbmarius/react-route-refresh-without-page-reload-1907テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol