なぜSWRを選んだのですか?


Data fetching


フロント・リポジトリからサーバにデータを要求し、応答を得る方法はいくつかあります.

1. UseEffect

  • の最も代表的な例は、Effect hookの使用である可能性がある.
  • function RenderComponent() {
      	const [data, setData] = useState<T | null>(null)
        const [loading, setLoading] = useState<boolean>(true)
        const [error, setError] = useState<boolean>(false)
      
    	useEffect(() => {
          (function() {
            fetch(url, options)
      			.then((response) => {
            		setData(response)
            	})
      			.catch((error) => {
            		setError(true)
            	})
            	.finally(() => { 
              		setLoading(false)
            	});
          })()
        }, 
                  
        if (loading) return <div>loading...</div>
      	if (error) return <div>error...</div>
      	return <div>data</div>
    }
    この方法は、データ要求に問題はありませんが、データをパッチするコンポーネントは、データのステータス(ロード、エラー、および成功)に注目する必要があります.データを修正するためのコンポーネントを記述するたびに、上記のボイラボードコードを記述するのは非常に非効率であり、今後の管理作業で非常に困難になる可能性があります.
    この問題を解決する方法はuseFetchというcustom hookです.

    2. useFetch ( custom hook )

    // useFetch.ts
    function useFetch(url) {
      const [data, setData] = useState<T | null>(null);
      const [loading, setLoading] = useState<boolean>(true);
      const [error, setError] = useState<boolean>(false);
      
      useEffect(() => {
          (function() {
            fetch(url, options)
      			.then((response) => {
            		setData(response)
            	})
      			.catch((error) => {
            		setError(true)
            	})
            	.finally(() => { 
              		setLoading(false)
            	});
          })()
      }, [url])
    
      return { data, loading, error }
    }
    
    export default useFetch;
    import useFetch from './useFetch'
    
    function RenderComponent() {
      	const {data, loading, error} = useFetch(url)
                  
        if (loading) return <div>loading...</div>
      	if (error) return <div>error...</div>
      	return <div>data</div>
    }
    useFetch hookを作成すると、データパッチが必要な構成部品からuseFetchをインポートするだけで、すべてのデータパッチステータスはuseFetchによって管理されます.ステータスロジックを変更するには、useFetchで変更するだけです.
    でもuseFetchで解決できないものがありますパッチ・データをすぐにグローバル・ステータスに管理しますか?たとえば、ユーザの情報(ニックネーム、プロファイル写真)は、多くのコンポーネントが書き込む必要があるデータである可能性があります.この場合、useFetchを使用してサーバにデータを要求する必要がありますか?サーバに大量のリクエストを送信し、サーバが負荷になります.

    3. Redux saga, Redux thunk


    ReduxライブラリRedux Saga、Redux Thunkなどは、グローバル・ステータス管理および非同期データ要求を解決するために使用されます.
    次の例ではredux sagaのコードのみが記録されています.
    // saga.js
    function* handleRequestUser() {
      while (true) {
        const action = yield take(REQUEST_USER);
        const { payload, error } = yield call(API.user, action.payload);
        if (payload && !error) {
          yield put(successUser(payload));
        } else {
          yield put(failureUser(error));
        }
      }
    }
    
    export default function* rootSaga() {
      yield fork(handleRequestUser);
    }
    上のコードでは、fork効果を使用してhandleRequestUsersaga taskを起動します.REQUEST USERの動作タイプがdispatchの場合、apiリクエストが発行されると、成功時には成功動作(successUser)が送信され、失敗時には失敗動作(failureUser)が送信される.どうですか.redux sagaを使用すると、非同期データ要求後、データとステータスはreduxグローバルストレージ領域に管理されます.
    しかし、すべてのapiリクエストが成功し、ステータス動作タイプを追加する必要があり、対応する作成が必要なボイラボードコードも増加し(もちろん、redux toolkitのようなライブラリがある)、次のswrで説明するが、特定の時間間隔でデータ補修を行う.また、クリック時にデータをパッチする機能も別途実施する必要があります.

    4. Swr


    今、swrを紹介します.swrは、上述したすべての欠点をカバーすることができる.
  • usSWRフック、
  • 実施しやすい
  • データパッチ状態(反応停止)
  • グローバルデータ管理(swr cache)
  • swrの機能
  • をクリックすると、データ
  • が自動的にリフレッシュされます.
  • 特定期間のデータリフレッシュ
  • のほか、swr option2
  • もあります.
    次のコードは、ピカと鼻のポータルサイトのコードの一部を抜粋し、簡単な修正を行いました.
    function LiveStreamingContents() {
    	const isDesktop = useIsDesktop();
    	const { data } = useSwr('/liveStreaming', fetcher, { suspense: true, revalidateOnFocus: true, refreshInterval: 5000 });
    
    	return (
    		<Slider className="container" dots infinite speed={500} slidesToShow={isDesktop ? 3 : 4} slidesToScroll={1}>
    			{data?.map((matches) => (
    				<Content key={matches.match_id} matchTeams={matches.match_name} gameCode={matches.game_code} leagueName={matches.league_name} />
    			))}
    		</Slider>
    	);
    }
    import LiveStreamingContents from './LiveStreamingContents';
    
    function LiveStreamingInfo() {
    	return (
    		<section className={styles.slider}>
    			<h2 className={styles.slider_title}>P&G 라이브 정보</h2>
    				<ErrorBoundary fallback=<div>error!</div>>
                  		<Suspense fallback=<div>..loading</div>>
                  			<LiveStreamingContents />
                    	</Suspense>
                  	</ErrorBoundary>
    			
    		</section>
    	);
    }
    
    export default LiveStreamingInfo;
    コードを簡単に説明すると、LiveStreamingContentsコンポーネントは、現在再生中の生放送情報をサーバから要求して表示します.ここで注意したいのはuserswrを用いたoption伝達の懸念である.懸念がtrueである場合、データが受信される前に、反応する懸念要素は、懸念されるfallback要素をレンダリングする(react suspense).宣言構成部品を作成すると、LiveStreamingContents構成部品はステータスに注目せず、データのみに注目してデータをレンダリングします.もっと直感的でしょう?
    また、swrは様々な機能を提供しています.サンプル・コードには、RevalidateOnFocusとrefreshIntervalの2種類しか適用されません.fetch option
    に表示されます.

    別のブラウザ・ステップをクリックし、既存のステップを再度クリックすると、revalidateOnFocus=trueがapiリクエストを自動的に発行します.
    さらに、swrは、サーバから取得したデータをswr cacheに格納し、cacheに同じキーで格納したデータを他のコンポーネントにグローバルに書き込むこともできる.

    SWRの適用


    現在開発中のpick&goポータルサイトは、各プラットフォーム(twitch、afreeca)からのlolおよびpubg生放送情報をサーバから受信している.ユーザがイベントを発行していない場合、リアルタイムブロードキャスト情報は自動的に更新されません.apiを定期的にリフレッシュする必要がある場合、swrのオプションで特定の時間周期的にデータを再参照する機能(refreshInterval)を調整し、特定の時間周期でデータを自動的にリフレッシュして、ユーザに最新のリアルタイムブロードキャスト情報を提供することができる.
    by James
    リファレンス
    https://swr.vercel.app/