javasctipt まとめ

#`event.preventDefault`の使い方

- クリックなどのイベントは、子要素から親要素へ伝播する(バブリング)
- `preventDefault()`はその要素のイベントをキャンセルし、`stopPropagation()`は親要素への伝播をキャンセルする
- `return false;`を使うと、その要素のイベントも親要素への伝播も両方キャンセルする

[参考](https://www.tam-tam.co.jp/tipsnote/javascript/post5050.html)
[参考2 具体例](http://www.koikikukan.com/archives/2013/11/21-023333.php)

ここでの`preventDefault()`は画面の更新ができないようにしている

```javascript
export default function reducer(state = initialState, action) {
  switch (action.type) {
    case 'HELLO_WORLD':
      return {
        ...state,
        hello: action.hello
      };

    default:
      return state
  }
}
```

`state=initialState`はデフォルト引数
`...state`は不明。多分可変長引数的なやつ？

### [JS]オブジェクトの分割導入
imageには現在の状態を代入します。
この `let {var} = this.obj` という書き方はオブジェクトの分割代入という構文で、`this.state` の `image` というプロパティが自動的に `let image` にセットされます。


## 困っていること
reactnativeでのフォームの実装の仕方がわからない
=>`redux-form`を使うことで解決を図っている

`tcomb-form-native`を結局使うことに

## 今後の設計

## 現状の課題
`Tab`はコンポーネントでないため`props`と`state`を渡すことができない！どうしよう...


## reduxの概念
reduxを用いればSPAはmodelのような形で実装できる。ただし、setterを持たない。

```js
{
  todos: [{
    text: 'Eat food',
    completed: true
  }, {
    text: 'Exercise',
    completed: false
  }],
  visibilityFilter: 'SHOW_COMPLETED'
}
```
そこで、`action`を通して`state`を変更する。
actionはプレーンなjavascript.

`reducer`は`action`と`state`を結びつける概念。
actionとstateを引数にとり、変更後のstateを返す関数という形で実装される。

大きいappを作る際にそういう関数(reducer)を書くのは至難なので、stateの一部を変更する関数を書く。

```js
function visibilityFilter(state = 'SHOW_ALL', action) {
  if (action.type === 'SET_VISIBILITY_FILTER') {
    return action.filter
  } else {
    return state
  }
}
 
function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return state.concat([{ text: action.text, completed: false }])
    case 'TOGGLE_TODO':
      return state.map(
        (todo, index) =>
          action.index === index
            ? { text: todo.text, completed: !todo.completed }
            : todo
      )
    default:
      return state
  }
}
```

以上二つのreducerを用いて対応するstateの`key`から全てのstateを変更する新しいreducerを書く。


```js
function todoApp(state = {}, action) {
  return {
    todos: todos(state.todos, action),
    visibilityFilter: visibilityFilter(state.visibilityFilter, action)
  }
}
```

**全てのstateはstoreに含まれる。**

## storeの役割

`This makes it easy to create universal apps, as the state from your server can be serialized and hydrated into the client with no extra coding effort`

とのこと。
全てのstateがstoreに含まれていれば、今まで困難だったUndo/Redoが簡単に実装できるようになる

```js 
console.log(store.getState())
 
/* Prints
{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux',
      completed: true,
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}
*/
```

## stateは読み込み専用
stateを更新する方法はただ一つ。何が起こったか示すオブジェクトである`action`を使うこと
このおかげで、viewやコールバックはstateを直接変更できない。その代わり、どのstateを変更したいかということを表明することができる。そして厳密な順序で一つ一つ処理が実行される。actionsはプレーンなオブジェクトのため、ログや再現やデバッグが容易となる。

pure reducerを書いてみればstate treeがいかにactionによって更新されるかが見て取れる。
reducerは前のstateを変更するのではなく、新しいstateを返すものだということには留意したい。

`Reducers are just pure functions that take the previous state and an action, and return the next state. Remember to return new state objects, instead of mutating the previous state. You can start with a single reducer, and as your app grows, split it off into smaller reducers that manage specific parts of the state tree. Because reducers are just functions, you can control the order in which they are called, pass additional data, or even make reusable reducers for common tasks such as pagination.`


```js
function visibilityFilter(state = 'SHOW_ALL', action) {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}
 
function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case 'COMPLETE_TODO':
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: true
          })
        }
        return todo
      })
    default:
      return state
  }
}
 
import { combineReducers, createStore } from 'redux'
const reducer = combineReducers({ visibilityFilter, todos })
const store = createStore(reducer)
```

## Action
actionはappからstoreにデータを送る唯一の手段。`store.dispatch()`でデータを送る。
新しくTodoを追加するアクションを以下に示す。

```js
const ADD_TODO = 'ADD_TODO'

{
  type: ADD_TODO,
  text: 'Build my first Redux app'
}
```

actionはプレーンなjavascriptのObject。どのようなアクションが実行されるかを示す`type`をもつ。
type以外のactionの構成は**自由だ**


`Note on Boilerplate
You don't have to define action type constants in a separate file, or even to define them at all. For a small project, it might be easier to just use string literals for action types. However, there are some benefits to explicitly declaring constants in larger codebases. Read Reducing Boilerplate for more practical tips on keeping your codebase clean.`

#Ajaxの復習をしよう

## object spread syntax
array spread operatorと同じで、オブジェクトを展開する。
本番環境ではbabelが必要だがReact Nativeでは安全に使用可能
[参考](https://redux.js.org/recipes/using-object-spread-operator)


## combineReducers()
以下の二つは同じ

```js
import { combineReducers } from 'redux'
 
const todoApp = combineReducers({
  visibilityFilter,
  todos
})
 
export default todoApp

```

```js
export default function todoApp(state = {}, action) {
  return {
    visibilityFilter: visibilityFilter(state.visibilityFilter, action),
    todos: todos(state.todos, action)
  }
}
```


## store
何を起こったかを示す`action`と
actionに基づいて`state`を変更する`reducer`
それらを合わせるものがstore

storeの役割 

- appのstateを保持する
- `getState()`経由でstateへのアクセスを許可する
- `dispatch(action)`経由でstateの更新を許可する
- `subscribe(listener)`でリスナーを登録する
- `subscribe(listener)`の戻り値に基づいてリスナーの登録解除を行う

**storeはappに1つのみ。データ処理のロジックを分割したいときは`reducer composition`を用いる**

`combineReducers()`を`createStore()`に渡すことで簡単にstoreを実装することができる

```js

import { createStore } from 'redux'
import todoApp from './reducers'
const store = createStore(todoApp)
```

## データフロー

# containerとpresentationalコンポーネント
### presentationalコンポーネント

- 見た目に関連している
- presentationalとcontainerの両方を内部的に含みうる。また、普通DOMのマークアップとスタイルを保持する
- `this.props.children`を経由してしばしば抑制(containment)を許可する。
- actionやstoreなど、appの残りの部分への依存がない
- どのようにデータがロードされ変更されるのかは特定しない
- propsのみからデータとコールバックを受け取る
- ほとんど自身のstateを持たない。持つときはデータではなくUIのstate
- 関数コンポーネントである

例
Page, Sidebar, Story, UserInfo, List

### containerコンポーネント

- どのように要素が働くかに関連する
- presentationalとcontainerの両方を内部にもつが、wrapping divをのぞいてDOMのマークアップを持つことはない。
- データと振る舞いを他のpresentational/containerコンポーネントに渡す
- fluxアクションを呼ぶ。また、それらをコールバックとしてpresentationalコンポーネントに渡す
- 結構ステートフル。データの源として使われがち
- 通常スクラッチで実装されるというよりreact reduxのconnect()のような上位のコンポーネントからによって生成される

例
UserPage, FollowersSidebar, StoryContainer, FollowedUserList.


# Todoリストを作るときのreact, reduxの構成
**react-reduxはpresentational, containerの構成に従う**

## presentational


# reduxの実装
`To use connect(), you need to define a special function called mapStateToProps that tells how to transform the current Redux store state into the props you want to pass to a presentational component you are wrapping. For example, VisibleTodoList needs to calculate todos to pass to the TodoList, so we define a function that filters the state.todos according to the state.visibilityFilter, and use it in its mapStateToProps:`

connect()を使うためには、`mapStateToProps`と呼ばれる特別な関数が必要である。それは、どのように現在の`store`が,wrapしているpresentationalコンポーネントに渡すpropsに変更するかを示す.
例えば、`VisibleTodoList`はTodoListに渡すためにtodosを計算する必要がある。だから我々はstate.visibilityFilterにもとづいてstate.todosをフィルターにかける関数を定義し、mapStateToPropsの中で使用する。


```js 
const getVisibleTodos = (todos, filter) => {
  switch (filter) {
    case 'SHOW_COMPLETED':
      return todos.filter(t => t.completed)
    case 'SHOW_ACTIVE':
      return todos.filter(t => !t.completed)
    case 'SHOW_ALL':
    default:
      return todos
  }
}

const mapStateToProps = state => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}
```

`In addition to reading the state, container components can dispatch actions. In a similar fashion, you can define a function called mapDispatchToProps() that receives the dispatch() method and returns callback props that you want to inject into the presentational component. For example, we want the VisibleTodoList to inject a prop called onTodoClick into the TodoList component, and we want onTodoClick to dispatch a TOGGLE_TODO action:`

stateを読むのに加えて、containerコンポーネントはactionsをdispatchすることができる。同様のやり方で、`mapDispatchToProps()`という関数を定義することもできる。それは`dispatch()`メソッドを受け取り,
presentationalなコンポーネントに挿入したいcallback props返す。例えば、onTodoClickと呼ばれるprop
をTodoListコンポーネントに渡すのにVisibleTodoListを必要とする。また、onTodoClickをTOGGLE_TODOアクションをdispatchするために必要とする