みなさんこんにちは、個別指導塾コミット塾長、AWESOME開発担当の船津です。
まだまだ全然ES6のアロー関数を使いこなせずにいます。結局function(){…}となっている方が見易いもので…
thisのスコープが変わるらしいのでアロー関数使ったほうが良い場面もあるのでしょうが、なかなか難しいですね。
ではでは始めていきます。
目次
今回のバージョンのgithubリポジトリ
今回はTodoリストらしく、「完了」、「未完了」を区別して表示、非表示を選択できるようにしましょう。
参考にしたのはこちらの2つ
公式サイト
http://redux.js.org/docs/basics/ExampleTodoList.html
いつもお世話になってます…
http://qiita.com/xkumiyu/items/1ba476b8043b71561f52
今回作るもの
今回は前回のまでの機能に少し手を加えていきます。
変更点のみ記述していきます。
それでは作っていきましょう。
##まずはお試し
actions/index.js
- 以下を追記しましょう
- タスクを表示するしないを判別するsetVisibilityFilterのactionを発行します。
- ‘SHOW_ALL’等の文字列を引数として受け取ります。
export const setVisibilityFilter = (filter) => { return { type: 'SET_VISIBILITY_FILTER', filter } }
reducers/visibilityFilter.js
- 発行されたアクションに対する処理を記述します。
- フィルターの内容を返すだけの関数です。
export default function visibilityFilter(state = 'SHOW_ACTIVE', action) { switch(action.type){ case 'SET_VISIBILITY_FILTER': return action.filter default: return state } }
conatainers/TodoApp.js
- todosとfilterをmapStateToPropsに渡して一括で受け取れるようにします。
- 詳しくは公式サイトで(まだあんまりわかってない)
function getVisibleTodos(todos, filter) { switch(filter) { case 'SHOW_ALL': return todos case 'SHOW_COMPLETED': return todos.filter((t) => t.completed) case 'SHOW_ACTIVE': return todos.filter((t) => !t.completed) } } function mapStateToProps(state) { return { todos: getVisibleTodos(state.todos, state.visibilityFilter) } }
動作を確かめてみよう
以下を追記して動作を確かめてみましょう。
テストするときだけlet store =
となっているところからlet
を消して、storeをグローバルにしておきましょう。
containers/TodoList.js
- 実際に
store.dispatch(setVisibilityFilter('SHOW_ALL'))
等を実行してみましょう。
<View style={styles.toggle}> <TouchableHighlight onPress={() => { store.dispatch(setVisibilityFilter('SHOW_ALL')) console.log(store.getState()) }} activeOpacity={75 / 100} underlayColor={"rgb(210,210,210)"}> <Text>show all</Text> </TouchableHighlight> <TouchableHighlight onPress={() => { store.dispatch(setVisibilityFilter('SHOW_COMPLETED')) console.log(store.getState()) }} activeOpacity={75 / 100} underlayColor={"rgb(210,210,210)"}> <Text>show completed</Text> </TouchableHighlight> <TouchableHighlight onPress={() => { store.dispatch(setVisibilityFilter('SHOW_ACTIVE')) console.log(store.getState()) }} activeOpacity={75 / 100} underlayColor={"rgb(210,210,210)"}> <Text>show active</Text> </TouchableHighlight> </View> --- const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', flexDirection: 'column', }, input: { height: 30, width: 100, borderWidth: 1, borderColor: "rgba(0,0,0,0.5)", borderRadius: 5, textAlign: 'center', }, inputarea: { flex: 1, justifyContent: 'center', }, toggle: { flex: 1, } });
ここまでできるとこんな感じになります。
デフォルトではアクティブなタスクのみ表示されるので、タスクを押すと表示されなくなります。
他のボタンを押すとアクティブでないタスクが表示されることが確認できます。
store.dispatch(setVisibilityFilter(‘SHOW_ACTIVE’)とかやってる部分をすっきりさせましょう
その前に
テストも終わったので
storeの頭にletを付けておきましょう。
containers/TodoApp.js
store.dispatch(setVisibilityFilter('SHOW_ACTIVE')
みたいなのをfilterTodo('SHOW_ACTIVE')
で呼び出せるようにします。- 親コンポーネントからTodoListコンポーネントにfilterTodoを渡します。
render() { const { todos, submitTask, onTodoClick, filterTodo } = this.props; return ( <TodoList todos={todos} submitTask={submitTask} onTodoClick={onTodoClick} filterTodo={filterTodo} /> ) } function mapDispatchToProps(dispatch) { return { submitTask: (text) => { dispatch(addTodo(text)) }, onTodoClick: (id) => { dispatch(toggleTodo(id)) }, filterTodo: (filter) => { dispatch(setVisibilityFilter(filter)) }, } }
components/TodoList.js
- 受け取った
filterTodo(filter)
をstore.dispatch(setVisibilityFilter(filter)
と差し替えます。
const { todos, submitTask, onTodoClick, filterTodo} = this.props; <View style={styles.toggle}> <TouchableHighlight onPress={() => filterTodo('SHOW_ALL')} activeOpacity={75 / 100} underlayColor={"rgb(210,210,210)"}> <Text>show all</Text> </TouchableHighlight> <TouchableHighlight onPress={() => filterTodo('SHOW_COMPLETED')} activeOpacity={75 / 100} underlayColor={"rgb(210,210,210)"}> <Text>show completed</Text> </TouchableHighlight> <TouchableHighlight onPress={() => filterTodo('SHOW_ACTIVE')} activeOpacity={75 / 100} underlayColor={"rgb(210,210,210)"}> <Text>show active</Text> </TouchableHighlight> </View>
次の課題
- アクションが増えてくると管理するのが面倒なのでミドルウェアを入れる?
- コンポーネント、関数をもっとまとめられそう
とりあえず写経します!!
Todoリストはおしまい?
おしまいですが、そのうちいままでの仕組みとDBを組み合わせてよりアプリらしくしていこうかなと思います。
realmとかっていうのが検索に引っかかるんですが、そんな大きなデータじゃないのでAsyncStorageとかで代用できないですかね?
知ってたら誰かおしえて下さい。