React Redux: 公式サイト「Basic Tutorial」の作例をフックで書き替える
React 16.8から、関数コンポーネントにReactの機能を加えるフック(hook)が採り入れられました。足並みを揃えてReact Redux 7.1.0に備わったのが、Reduxにつなげるフックです。React Redux公式「Basic Tutorial」の作例「Todo App with Redux」は、残念ながらReact 16.4.2でつくられ、どちらのフックも使われていません。そこで、フック対応に書き替えてみようというのが本稿のお題です。
クラスコンポーネントを関数コンポーネントに書き替える
まず、モジュールsrc/components/AddTodo.js
は、コンポーネントに状態(state
)をもたせるため、クラスで定められています。ReactのフックuseState()
を使って、関数コンポーネントに直しましょう(「React Hooks: クラスのコンポーネントをuseState()で関数に書き替える」参照)。関数コンポーネントの中ではthis
参照がなくなることにご注目ください。
// import React from 'react';
import React, { useState } from 'react';
// class AddTodo extends React.Component {
const AddTodo = ({ addTodo }) => {
/* constructor(props) {
super(props);
this.state = { input: '' };
} */
const [input, setInput] = useState('');
// updateInput = input => {
const updateInput = input => {
// this.setState({ input });
setInput(input);
};
// handleAddTodo = () => {
const handleAddTodo = () => {
// this.props.addTodo(this.state.input);
addTodo(input);
// this.setState({ input: '' });
setInput('');
};
// render() {
return (
<div>
<input
// onChange={e => this.updateInput(e.target.value)}
onChange={e => updateInput(e.target.value)}
// value={this.state.input}
value={input}
/>
{/* <button className='add-todo' onClick={this.handleAddTodo}> */}
<button className='add-todo' onClick={handleAddTodo}>
Add Todo
</button>
</div>
);
// }
};
useDispatch()を使う
つぎに、React Reduxのフックを使ってゆきます。connect()
関数の第2引数に与え、アクションを発行するdispatch()
につなげるフックがuseDispatch()
です。アクションクリエーター(addTodo
)は、フックから返された関数(dispatch()
)で呼び出します。
// import { connect } from 'react-redux';
import { useDispatch } from 'react-redux';
// const AddTodo = ({ addTodo }) => {
const AddTodo = () => {
const dispatch = useDispatch();
const handleAddTodo = () => {
// addTodo(input);
dispatch(addTodo(input));
};
};
/* export default connect(
null,
{ addTodo }
)(AddTodo); */
export default AddTodo;
これでモジュールsrc/components/AddTodo.js
が純粋な関数コンポーネントになりました。src/components/Todo.js
も、同じようにuseDispatch()
でconnect()
のラップが外せます。
// import { connect } from 'react-redux';
import { useDispatch } from 'react-redux';
import cx from 'classnames';
import { toggleTodo } from '../redux/actions';
// const Todo = ({ todo, toggleTodo }) => (
const Todo = ({ todo }) => {
const dispatch = useDispatch();
return (
// <li className='todo-item' onClick={() => toggleTodo(todo.id)}>
<li className='todo-item' onClick={() => dispatch(toggleTodo(todo.id))}>
</li>
);
}
/* export default connect(
null,
{ toggleTodo }
)(Todo); */
export default Todo;
useSelector()を使う
connect()
の第1引数(mapStateToProps
)が担う、Storeから状態(state
)を取り出すフックがuseSelector()
です。渡すのは関数で、引数(state
)の状態から処理した値を返します。モジュールsrc/components/TodoList.js
は、つぎのように書き替えればよいでしょう。
// import { connect } from 'react-redux';
import { useSelector } from 'react-redux';
// const TodoList = ({ todos }) => (
const TodoList = () => {
const todos = useSelector(state => {
const visibilityFilter = state.visibilityFilter;
const todos = getTodosByVisibilityFilter(state, visibilityFilter);
return todos;
});
}
/* const mapStateToProps = state => {
const { visibilityFilter } = state;
const todos = getTodosByVisibilityFilter(state, visibilityFilter);
return { todos };
};
export default connect(mapStateToProps)(TodoList); */
export default TodoList;
残るモジュールsrc/components/VisibilityFilters.js
は、connect()
にふたつの引数が与えられています。したがって、フックもuseSelector()
とuseDispatch()
をともに使わなければなりません。
// import { connect } from 'react-redux';
import { useSelector, useDispatch } from 'react-redux';
// const VisibilityFilters = ({ activeFilter, setFilter }) => {
const VisibilityFilters = () => {
const activeFilter = useSelector(state => state.visibilityFilter);
const dispatch = useDispatch();
return (
<div className='visibility-filters'>
{Object.keys(VISIBILITY_FILTERS).map(filterKey => {
const currentFilter = VISIBILITY_FILTERS[filterKey];
return (
<span
onClick={() => {
// setFilter(currentFilter);
dispatch(setFilter(currentFilter));
}}
>
{currentFilter}
</span>
);
})}
</div>
);
};
/* const mapStateToProps = state => {
return { activeFilter: state.visibilityFilter };
};
export default connect(
mapStateToProps,
{ setFilter }
)(VisibilityFilters); */
export default VisibilityFilters;
以上でReact Redux公式「Basic Tutorial」の作例が、フックを使った純粋な関数コンポーネントに書き直せました。でき上がりはCodeSandboxに「Todo App with Redux using Hooks」として公開しました。
Author And Source
この問題について(React Redux: 公式サイト「Basic Tutorial」の作例をフックで書き替える), 我々は、より多くの情報をここで見つけました https://qiita.com/FumioNonaka/items/2fd4e0a2ae240b66d903著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .