React 開発者向けの包括的な Redux ツールキットのメモ
? Redux ツールキットのメモ ?
Redux とは何ですか?
Redux は、アプリケーションの状態を個別に管理する JS アプリ用の柔軟な状態コンテナーです。アプリケーションの状態を 1 つのストアで管理するため、アプリ全体にわたる複雑な状態ロジックの処理が容易になります。
Redux を使用する理由
通常のフローでは、コンポーネント間で状態を渡すためにプロップドリルを行う必要があります。一部のレベルではここでの状態を必要としませんが、これは負担です。また、大規模な中型アプリの状態を引き上げるには構造的な変更が必要なため、スケーラブルなソリューションではありません。だからこそ、状態を管理するために redux が必要なのです。ここでのすべての状態はストアに保持され、必要なコンポーネントはそのストアにサブスクライブするだけで済みます。 Redux は、一方向のデータ フローを強制することで、予測可能な状態管理、デバッグの容易化、スケーラビリティの向上を保証します。
コア Redux コンポーネント:
アクション: 何が起こったかを説明するオブジェクト。通常、これにはタイプとオプションのペイロードが含まれます。 (コマンド)
Dispatch: 状態を更新するためにストアにアクションを送信するために使用される関数。 (イベント発生中)
Reducer: 現在の状態とアクションを受け取り、新しい状態を返す純粋な関数。 (アクションのディスパッチ時にトリガーされる関数)
インストール: npm i @reduxjs/toolkit reverse-redux
Redux ワークフロー:
スライスの作成:
スライスは、単一の機能に対する Redux Reducer ロジックとアクションのコレクションです。 prepare コールバックを使用すると、アクション ペイロードがリデューサーに到達する前にカスタマイズできます。
import { createSlice, nanoid } from "@reduxjs/toolkit"; const postSlice = createSlice({ name: "posts", initialState: [], reducers: { addPost: { reducer: (state, action) => { state.push(action.payload); }, prepare: (title, content) => ({ payload: { id: nanoid(), title, content }, }), }, deletePost: (state, action) => { return state.filter((post) => post.id != action.payload); }, }, }); export const { addPost, deletePost } = postSlice.actions; export default postSlice.reducer;
ストアの作成:
import { configureStore } from "@reduxjs/toolkit"; import postReducer from "../features/posts/postSlice"; export const store = configureStore({ reducer: { posts: postReducer }, });
プロバイダーでラップ:
import { Provider } from "react-redux"; import { store } from "./app/store.jsx"; createRoot(document.getElementById("root")).render( <StrictMode> <Provider store={store}> <App /> </Provider> </StrictMode> );
コンポーネントで使用:
const PostList = ({ onEdit }) => { const posts = useSelector((state) => state.posts); const dispatch = useDispatch(); return ( <div className="w-full grid grid-cols-1 gap-6 mt-12"> {posts.map((post) => ( <div key={post.id}></div> ))} </div> ); };
Redux ブラウザ拡張機能: Redux DevTools
const store = configureStore({ reducer: rootReducer, devTools: process.env.NODE_ENV !== 'production', });
Redux での非同期操作 (Redux サンク):
Redux では、非同期操作 (API 呼び出しなど) はミドルウェアを使用して処理されます。これは、Redux がデフォルトで同期状態更新のみをサポートしているためです。非同期操作を処理するための最も一般的なミドルウェアは、Redux Thunk、createAsyncThunk を備えた Redux Toolkit (RTK)、および Redux Saga です。
実装:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; // Fetch all posts export const fetchPosts = createAsyncThunk('posts/fetchPosts', async () => { const response = await fetch('https://jsonplaceholder.typicode.com/posts'); return response.json(); }); // Initial State const initialState = { posts: [], post: null, loading: false, error: null, }; // Slice const postsSlice = createSlice({ name: 'posts', initialState, reducers: {}, extraReducers: (builder) => { builder // Fetch all posts .addCase(fetchPosts.pending, (state) => { state.loading = true; }) .addCase(fetchPosts.fulfilled, (state, action) => { state.loading = false; state.posts = action.payload; }) .addCase(fetchPosts.rejected, (state, action) => { state.loading = false; state.error = action.error.message; }) }, }); export default postsSlice.reducer;
使用例:
import React, { useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { fetchPosts, createPost, updatePost, deletePost } from './postsSlice'; const Posts = () => { const dispatch = useDispatch(); const { posts, loading, error } = useSelector((state) =>state.posts); useEffect(() => { dispatch(fetchPosts()); }, [dispatch]); const handleCreate = () => { dispatch(createPost({ title: 'New Post', body: 'This is a new post' })); }; if (loading) return <p>Loading...</p>; if (error) return <p>Error: {error}</p>; return ( <div> <h1>Posts</h1> <button onClick={handleCreate}>Create Post</button> </div> ); }; export default Posts;
ミドルウェア
Redux のミドルウェアはディスパッチされたアクションをインターセプトし、ロギング、クラッシュ レポート、または非同期ロジックの処理を可能にします。ミドルウェアを使用すると、ディスパッチプロセスをカスタマイズできます。
const blogPostMiddleware = (storeAPI) => (next) => (action) => { if (action.type === 'posts/publishPost') { const contentLength = action.payload.content.length; if (contentLength < 50) { console.warn('Post content is too short. Must be at least 50 characters.'); return; } console.log('Publishing post:', action.payload.title); } return next(action); }; const store = configureStore({ reducer: rootReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(blogPostMiddleware), });
セレクター
セレクターは、状態の特定の部分にアクセスするのに役立ちます。
export const selectCount = (state) => state.counter.value;
エラー処理
適切な状態管理によりエラーを効果的に処理します。
import { createSlice, nanoid } from "@reduxjs/toolkit"; const postSlice = createSlice({ name: "posts", initialState: [], reducers: { addPost: { reducer: (state, action) => { state.push(action.payload); }, prepare: (title, content) => ({ payload: { id: nanoid(), title, content }, }), }, deletePost: (state, action) => { return state.filter((post) => post.id != action.payload); }, }, }); export const { addPost, deletePost } = postSlice.actions; export default postSlice.reducer;
RTK クエリ (簡易データ取得)
RTK クエリは、データのフェッチ、キャッシュ、同期を簡素化します。 RTK クエリはリクエストを自動的にキャッシュし、不必要な再フェッチを回避してパフォーマンスを向上させます。
RTK クエリのセットアップ
import { configureStore } from "@reduxjs/toolkit"; import postReducer from "../features/posts/postSlice"; export const store = configureStore({ reducer: { posts: postReducer }, });
コンポーネントでの使用法
import { Provider } from "react-redux"; import { store } from "./app/store.jsx"; createRoot(document.getElementById("root")).render( <StrictMode> <Provider store={store}> <App /> </Provider> </StrictMode> );
Immer による不変の更新
Immer を使用すると、内部で更新を不変に保ちながら、状態を直接「変更」するロジックを作成できます。
const PostList = ({ onEdit }) => { const posts = useSelector((state) => state.posts); const dispatch = useDispatch(); return ( <div className="w-full grid grid-cols-1 gap-6 mt-12"> {posts.map((post) => ( <div key={post.id}></div> ))} </div> ); };
突然変異と不変
Mutate: データを直接変更します。たとえば、オブジェクトまたは配列を変更します。
不変: データを直接変更する代わりに、元のデータはそのままにして、変更を適用した新しいコピーを作成します。
Immer の仕組み
Immer は、データを変更している (つまり、データを直接変更している) ように見えるコードを作成するのに役立ちますが、内部では自動的に変更を不変に保ちます。これは、JavaScript で不変のデータ構造を扱うときによくあるバグを回避するのに役立ちます。
例: Immer なし (突然変異):
const store = configureStore({ reducer: rootReducer, devTools: process.env.NODE_ENV !== 'production', });
Immer あり (不変性):
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; // Fetch all posts export const fetchPosts = createAsyncThunk('posts/fetchPosts', async () => { const response = await fetch('https://jsonplaceholder.typicode.com/posts'); return response.json(); }); // Initial State const initialState = { posts: [], post: null, loading: false, error: null, }; // Slice const postsSlice = createSlice({ name: 'posts', initialState, reducers: {}, extraReducers: (builder) => { builder // Fetch all posts .addCase(fetchPosts.pending, (state) => { state.loading = true; }) .addCase(fetchPosts.fulfilled, (state, action) => { state.loading = false; state.posts = action.payload; }) .addCase(fetchPosts.rejected, (state, action) => { state.loading = false; state.error = action.error.message; }) }, }); export default postsSlice.reducer;
これにより、手動で状態を複製して更新する必要がなくなるため、Redux (またはその他の状態管理) の操作が容易になります。 Immer はそれを自動的に実行します。
Redux 永続化:
ページが更新されても Redux 状態を維持するには、Redux Persist を統合します。これにより、Redux の状態がローカル ストレージまたはセッション ストレージに保存され、アプリが更新されたときに再ロードされます。
インストール:
npm install redux-persist
実装:
import React, { useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { fetchPosts, createPost, updatePost, deletePost } from './postsSlice'; const Posts = () => { const dispatch = useDispatch(); const { posts, loading, error } = useSelector((state) =>state.posts); useEffect(() => { dispatch(fetchPosts()); }, [dispatch]); const handleCreate = () => { dispatch(createPost({ title: 'New Post', body: 'This is a new post' })); }; if (loading) return <p>Loading...</p>; if (error) return <p>Error: {error}</p>; return ( <div> <h1>Posts</h1> <button onClick={handleCreate}>Create Post</button> </div> ); }; export default Posts;
パーシットゲートでラップ:
const blogPostMiddleware = (storeAPI) => (next) => (action) => { if (action.type === 'posts/publishPost') { const contentLength = action.payload.content.length; if (contentLength < 50) { console.warn('Post content is too short. Must be at least 50 characters.'); return; } console.log('Publishing post:', action.payload.title); } return next(action); }; const store = configureStore({ reducer: rootReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(blogPostMiddleware), });
オプションの拡張機能
localStorage の代わりに sessionStorage を使用します:
ストレージをセッションベースに変更します (ブラウザを閉じるとクリアされます):
initialState: { items: [], status: 'idle', error: null, }, .addCase(fetchData.rejected, (state, action) => { state.status = 'failed'; state.error = action.error.message; });
選択的永続性:
状態の特定のスライスのみを永続化します:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; const api = createApi({ reducerPath: 'api', baseQuery: fetchBaseQuery({ baseUrl: 'https://jsonplaceholder.typicode.com' }), endpoints: (builder) => ({ getPosts: builder.query({ query: () => '/posts', }), getPostById: builder.query({ query: (id) => `/posts/${id}`, }), createPost: builder.mutation({ query: (newPost) => ({ url: '/posts', method: 'POST', body: newPost, }), }), updatePost: builder.mutation({ query: ({ id, ...updatedPost }) => ({ url: `/posts/${id}`, method: 'PUT', body: updatedPost, }), }), deletePost: builder.mutation({ query: (id) => ({ url: `/posts/${id}`, method: 'DELETE', }), }), }), }); export const { useGetPostsQuery, useGetPostByIdQuery, useCreatePostMutation, useUpdatePostMutation, useDeletePostMutation, } = api; export default api;
CRUD 機能を備えた React、redux、ant デザインを使用してシンプルなブログ プロジェクトを作成しました。ぜひチェックしてみてください。
プロジェクト リンク - Redux ブログ アプリ
? Redux Toolkit をマスターして React アプリをレベルアップしましょう!
以上がReact 開発者向けの包括的な Redux ツールキットのメモの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。
