HTML5テクニカルノート
React + Redux入門 07: React ReduxのフックuseDispatch()とuseSelector()を使う
- ID: FN2004004
- Technique: HTML5 / ECMAScript 2015
- Library: React 16.13.1 / Redux 4.0.5 / React Redux 7.2.0
React Redux 7.1.0からフック(Hook)が備わりました。React標準のフックが状態などの機能を関数コンポーネントにつなぐ(hook into)のに対して、ReduxのStoreにつなぐのがReact Reduxのフックです。高階(Higher-Order)コンポーネントのconnect()
を使わずに済み、コードの組み立てがすっきりします。
01 useDispatch()でStoreからdispatch()を参照する
connect()
でラップしたコンポーネントを、フックで書き替えてみるのがわかりやすいでしょう。「React + Redux入門 02: フィールドに入力したテキストを項目リストに加える」のつぎの作例(サンプル001)で試すことにします。
サンプル001■react-redux-todos-02
まず、モジュールsrc/components/AddTodo.js
です。connect()
が引数なしに呼び出されて、ラップされた関数コンポーネント(AddTodo
)は、受け取ったprops
からdispatch()
を取り出して使っています。ReduxのStroreからdispatch
を参照するのがuseDispatch()
です。このフックを用いることにより、つぎのようにconnect()
によるラップが外せます。
src/components/AddTodo.js// import { connect } from 'react-redux'; import { useDispatch } from 'react-redux'; // const AddTodo = ({ dispatch }) => { const AddTodo = () => { const dispatch = useDispatch(); return ( <div> <form onSubmit={(event) => { // dispatch(addTodo(text)); dispatch(addTodo(text)); }}> </form> </div> ); }; // export default connect()(AddTodo); export default AddTodo;
02 useSelector()でStoreのstateを参照して処理する
もうひとつ手を加えるのは、モジュールsrc/components/TodoList.js
です。connect()
に渡す第1引数(mapStateToProps
)で、state
からデータ(todos
)を取り出して関数コンポーネントの引数(props
)に与えていました。Storeのstate
を参照するフックはuseSelector()
です。引数に渡した関数はstate
を受け取るので、取り出したい値を返してください。connect()
とともに、その第1引数として定めた関数も要らなくなりました。
src/components/TodoList.js// import { connect } from 'react-redux'; import { useSelector } from 'react-redux'; // const TodoList = ({ todos }) => ( const TodoList = () => { const todos = useSelector((state) => state.todos); }; /* const mapStateToProps = (state) => ({ todos: state.todos }); */ /* export default connect( mapStateToProps )(TodoList); */ export default TodoList;
03 React Reduxのフックで書き直した作例
以上ふたつのモジュールをReact Reduxのフックに書き替えたことにより、前掲サンプル001からconnect()
の呼び出しがなくなりました。ふたつのモジュールの記述全体をまとめたのが、以下のコード001と002です。併せて、動きを確かめるための書き直した作例を、CodeSandboxに公開しました(サンプル002)。今回はごく簡単なコードサンプルで、試したふたつのフックの構文ももっともシンプルなものです。次回は、Redux公式サイトの「Example: Todo List」をふたつのフックで書き直します。
コード001■src/components/AddTodo.js
import React from "react";
import { useDispatch } from "react-redux";
import { addTodo } from "../actions";
const AddTodo = () => {
const dispatch = useDispatch();
let input;
return (
<div>
<form
onSubmit={event => {
event.preventDefault();
const text = input.value.trim();
input.value = "";
if (!text) {
return;
}
dispatch(addTodo(text));
}}
>
<input ref={element => (input = element)} />
<button type="submit">Add Todo</button>
</form>
</div>
);
};
export default AddTodo;
コード002■src/components/TodoList.js
import React from "react";
import { useSelector } from "react-redux";
import Todo from "./Todo";
const TodoList = () => {
const todos = useSelector(state => state.todos);
return (
<ul className="todo-list">
{todos.map(todo => (
<Todo key={todo.id} {...todo} />
))}
</ul>
);
};
export default TodoList;
サンプル002■react-redux-todos-07
React + Redux入門
- React + Redux入門 01: テキスト入力のフォームをつくる
- React + Redux入門 02: フィールドに入力したテキストを項目リストに加える
- React + Redux入門 03: 項目の処理済みと未処理でスタイルを変える
- React + Redux入門 04: リスト項目のフィルタを加える
- React + Redux入門 05: PropTypesで型を確かめる
- React + Redux入門 06: コンポーネントをプレゼンテーションとコンテナに分ける
- React + Redux入門 07: React ReduxのフックuseDispatch()とuseSelector()を使う
- React + Redux入門 08: Redux公式サイトのTodoリストの作例をフックuseDispatch()とuseSelector()で書き替える
作成者: 野中文雄
作成日: 2020年04月29日
Copyright © 2001-2020 Fumio Nonaka. All rights reserved.