Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix sample code in Ch07 & Ch08 #73

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 18 additions & 20 deletions Ch07/react-redux-real-world-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ $ npm install --save react react-dom redux react-redux immutable redux-actions r
```

```
$ npm install --save-dev babel-core babel-eslint babel-loader babel-preset-es2015 babel-preset-react eslint eslint-config-airbnb eslint-loader eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react html-webpack-plugin webpack webpack-dev-server
$ npm install --save-dev babel-core babel-eslint babel-loader babel-preset-es2015 babel-preset-react eslint eslint-config-airbnb eslint-loader eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react html-webpack-plugin webpack webpack-dev-server redux-logger
```

安裝好後我們可以設計一下我們的資料夾結構,首先我們在根目錄建立 `src`,放置 `script` 的 `source` 。在 `components` 資料夾中我們會放置所有 `components`(個別元件資料夾中會用 `index.js` 輸出元件,讓引入元件更簡潔)、`containers`(負責和 store 互動取得 state),另外還有 `actions`、`constants`、`reducers`、`store`,其餘設定檔則放置於根目錄下。
Expand Down Expand Up @@ -81,13 +81,13 @@ ReactDOM.render(
```javascript
import React from 'react';
import ReactDOM from 'react-dom';
import TodoHeaderContainer from '../../containers/TodoHeaderContainer';
import TodoListContainer from '../../containers/TodoListContainer';
import TodoHeader from '../TodoHeader';
import TodoList from '../TodoList';

const Main = () => (
<div>
<TodoHeaderContainer />
<TodoListContainer />
<TodoHeader />
<TodoList />
</div>
);

Expand Down Expand Up @@ -151,6 +151,10 @@ export const TodoState = Immutable.fromJS({
completed: false,
}
});

export const UiState = Immutable.fromJS({
'myUIState': '',
});
```

接下來我們要討論的是 Reducers 的部份,在 `todoReducers` 中我們會根據接收到的 action 進行 mapping 到對應的處理函式並傳入夾帶的 `payload` 資料(這邊我們使用 [redux-actions](https://github.com/acdlite/redux-actions) 來進行 mapping,使用上比傳統的 switch 更為簡潔)。Reducers 接收到 action 的處理方式為 `(initialState, action) => newState`,最終會回傳一個新的 state,而非更改原來的 state,所以這邊我們使用 `ImmutableJS`。
Expand Down Expand Up @@ -183,7 +187,7 @@ export default todoReducers;

```javascript
import { handleActions } from 'redux-actions';
import UiState from '../../constants/models';
import { UiState } from '../../constants/models';

export default handleActions({
SHOW: (state, { payload }) => (
Expand Down Expand Up @@ -246,7 +250,6 @@ export { default } from './configureStore';
import React from 'react';
import ReactDOM from 'react-dom';
import { connect } from 'react-redux';
import TodoHeader from '../../components/TodoHeader';

// 將欲使用的 actions 引入
import {
Expand All @@ -271,11 +274,6 @@ const mapDispatchToProps = (dispatch) => ({
}
});

export default connect(
mapStateToProps,
mapDispatchToProps,
)(TodoHeader);

// 開始建設 Component 並使用 connect 進來的 props 並綁定事件(onChange、onClick)。注意我們的 state 因為是使用 `ImmutableJS` 所以要用 `get()` 取值
const TodoHeader = ({
onChangeText,
Expand All @@ -289,7 +287,10 @@ const TodoHeader = ({
</div>
);

export default TodoHeader;
export default connect(
mapStateToProps,
mapDispatchToProps,
)(TodoHeader);
```

以下是 `src/components/TodoList/TodoList.js` 的部份:
Expand All @@ -298,7 +299,6 @@ export default TodoHeader;
import React from 'react';
import ReactDOM from 'react-dom';
import { connect } from 'react-redux';
import TodoList from '../../components/TodoList';

import {
deleteTodo,
Expand All @@ -315,11 +315,6 @@ const mapDispatchToProps = (dispatch) => ({
)
});

export default connect(
mapStateToProps,
mapDispatchToProps,
)(TodoList);

// Component 部分值的注意的是 todos state 是透過 map function 去迭代出元素,由於要讓 React JSX 可以渲染並保持傳入觸發 event state 的 immutable,所以需使用 toJS() 轉換 component of array。
const TodoList = ({
todos,
Expand All @@ -339,7 +334,10 @@ const TodoList = ({
</div>
);

export default TodoList;
export default connect(
mapStateToProps,
mapDispatchToProps,
)(TodoList);
```

若是一切順利的話就可以在瀏覽器上看到自己努力的成果囉!(因為我們有使用 `redux-logger` 所以打開 console 會看到 action 和 state 的變化情形,但記得在 `production` 環境要拿掉)
Expand Down
18 changes: 18 additions & 0 deletions Ch08/container-presentational-component-.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,24 @@ const TodoList = ({
export default TodoList;
```

以下是 `src/components/Main/Main.js` 的部份:

```javascript
import React from 'react';
import ReactDOM from 'react-dom';
import TodoHeaderContainer from '../../containers/TodoHeaderContainer';
import TodoListContainer from '../../containers/TodoListContainer';

const Main = () => (
<div>
<TodoHeaderContainer />
<TodoListContainer />
</div>
);

export default Main;
```

## 總結
That's it!透過區分 Container 與 Presentational Components 可以讓程式架構和職責更清楚了!接下來我們將運用我們所學實際開發兩個貼近生活的專案,讓讀者更加熟悉 React 生態系如何應用於實務上。

Expand Down