0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Redux ExampleのTodoListをReact Native(expo)に置き換えて解説-ToggleTodo編

Last updated at Posted at 2020-09-27

Redux ExampleのTodoListをReact Native(expo)に置き換えて解説のToggleTodo編です。
AddTodo編は以下です。
Redux ExampleのTodoListをReact Native(expo)に置き換えて解説AddTodo編

注:僕は掛け出しエンジニアであり、自分の勉強としての投稿という面もあるので、もしミスや勘違い、ベストプラクティスではない、等がありましたら、コメントしていただけると幸いです。

#TODOに属性を追加
まずは、todoにcomplete属性を追加してtodoが完了済みなのかactive状態なのかを判定できるようにします。初期値はfalseにしておきます。

reducers/todos.js
const todoReducers = (state = [], action) => {
    switch(action.type){
        case 'ADD_TODO':
            return [
                ...state,
                {
                    id: action.id,
                    text: action.text,
                    completed: false //追加
                }
            ]
        default:
            return state
    }
}

export default todoReducers

Todoのcompleted属性がtrueかfalseによって見た目を変えたいので、TodoListコンポーネントを修正します。

components/TodoList.js
class TodoList extends Component {
  render() {
    return (
      <View>
        <FlatList
          data={this.props.todos}
          renderItem={({ item }) => (
            <View style={styles.todoList}>
              <Text
                style={{ 
                 textDecorationLine: item.completed ? "line-through" : "none",
                }} //追加↑
              >
                {item.text}
              </Text>
            </View>
          )}
          keyExtractor={(item) => item.id.toString()}
        />
      </View>
    );
  }
}

ここで、動作確認のため、reducers/todos.jsのcompleted属性をtrueにしてみましょう。todoに斜線が引かれていると思います。

#Actionからcompleted属性を操作する
次に、上記でやったtrue,falseの操作をActionを経由して操作できるようにしましょう。

まずはActionCreatorを作成します。どのtodoに横線を引くかを判別するためにidを取得します。

src/actions/index.js

let nextTodoId = 0
export const addTodo = text => ({
    type: 'ADD_TODO',
    id: nextTodoId++,
    text
})    

//追加
export const toggleTodo = (id) => {
  return {
    type: "TOGGLE_TODO",
    id,
  };
};

reducersも変更します。

reducers/todos.js
const todoReducers = (state = [], action) => {
  switch (action.type) {
    case "ADD_TODO":
      return [
        ...state,
        {
          id: action.id,
          text: action.text,
          completed: true,
        },
      ];
    case "TOGGLE_TODO": //追加
      return state.map((todo) =>
        todo.id === action.id ? { ...todo, completed: !todo.completed } : todo
      );
    default:
      return state;
  }
};

export default todoReducers;

やっていることとしては、stateに保存されている全てのtodoについて、それぞれのidとActionCreatorに渡された、横線を引きたいtodoのidを比べて、一致したらそのtodoのcompleted属性を逆転させるというものです。

ここで、例の如くApp.jsから動作確認をしてみましょう
App.jsに以下を追加してみましょう。

App.js
import { addTodo, toggleTodo } from './actions'

store.dispatch(addTodo('Hello React!'))
store.dispatch(toggleTodo(0))

画面をみてみると斜線が引かれたtodoが追加されているはずです。

#Todoをクリックしてcompleted属性を操作できるようにする

それでは、画面上からtodoの完了、未完了の操作ができるようにしましょう。mapDispatchToPropsを作成します。
これはcomponentで(今回で言えばTodoListで)dispatchをpropsとして渡せるものです。

こうすることで、component側ではthis.props.onTodoClick(id)の形で先ほどApp.jsでやったdispatch(toggleTodo(0))みたいなことができるようになります。

containers/VisibleTodoList.js
import { connect } from "react-redux";
import TodoList from "../components/TodoList";
import { toggleTodo } from "../actions"; //追加

const mapStateToProps = (state) => {
  return { todos: state.todoReducers };
};

//追加
const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id));
    },
  };
};

//追加
const VisibleTodoList = connect(mapStateToProps, mapDispatchToProps)(TodoList);
export default VisibleTodoList;

これでTodoListの方でonTodoClickが使えるようになったので、追加してみましょう。

components/TodoList.js
return (
      <View>
        <FlatList
          data={this.props.todos}
          renderItem={({ item }) => (
            <View style={styles.todoList}>
              <Text
                onPress={() => this.props.onTodoClick(item.id)}
                style={{
                  textDecorationLine: item.completed ? "line-through" : "none",
                }}
              >
                {item.text}
              </Text>
            </View>
          )}
          keyExtractor={(item) => item.id.toString()}
        />
      </View>
    );

これでtodoをクリックすると該当のtodoに斜線が引かれます。

ToggleTodo編は完成です!
お手元のシミュレーターでお試しください。
ここまでのソースコードはGitHubに上げていますのでご参考ください。

次回は表示するTodoをcompleted属性によって切り替える「FilterTodo」機能を実装していきます。

##参考
Redux ExampleのTodo Listをはじめからていねいに(2)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?