記得昨天 Redux 好朋友說今天要透過例子讓我更加了解運作的部分,而今天要先關於處理同步資料時的運作方式。
此外,還特地從元件中的 state 、事件一步步開始說明,然後再把 state 中的資料與事件搬到 Redux 中,真的很貼心。
接著讓我們看看提供的例子:
這邊 Redux 好朋友先描述了關於這個測試例子的操作情境:
相關測試範例,點擊前往
接著就是今天的重頭戲,將 state 與事件搬到 Redux 中。
這邊 Redux 好朋友再次幫我們條列的一個流程:
接著讓我們看看在範例中依序的設定:
相關測試範例,點擊前往
首先是安裝 redux, react-redux,這部分應該沒有難度,只需要注意版本的問題,在 React 版本 > 16 以上才可以使用。
接著會將幾個流程一次設定好,在 index.js 中:
// index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { createStore } from "redux";
import { rootReducer } from "./store/rootReducer";
import { Provider } from "react-redux";
const rootElement = document.getElementById("root");
const store = createStore(rootReducer);
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
rootElement
);
接著我們在 React 元件中設定:
import React, { Component } from "react";
import { connect } from "react-redux";
import "./styles.css";
class App extends Component {
render() {
return (
<div className="App">
<h2>數字: {this.props.number}</h2>
<button onClick={this.props.incrementHandler}>點擊 + 1</button>
<button onClick={this.props.decrementHandler}>點擊 - 1</button>
<button
onClick={() => {
this.props.incrementTenNumberHandler(this.props.number);
}}
>
由當前數字 + 10
</button>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
number: state.number
};
};
const mapDispatchToProps = (dispatch) => {
return {
incrementHandler: () => dispatch({ type: "INCREMENTHANDLER" }),
decrementHandler: () => dispatch({ type: "DECREMENTHANDLER" }),
incrementTenNumberHandler: (number) =>
dispatch({
type: "INCREMENTTENNUMBERHANDLER",
payload: {
number
}
})
};
};
export default connect(mapStateToProps, mapDispatchToProps)(App);
在 rootReducer 方法中的設定,透過判斷 action.type 決定觸發哪一個更新 state 的流程。
const initialState = {
number: 0
};
export const rootReducer = (state = initialState, action) => {
switch (action.type) {
case "INCREMENTHANDLER":
return {
number: state.number + 1
};
case "DECREMENTHANDLER":
return {
number: state.number - 1
};
case "INCREMENTTENNUMBERHANDLER":
return {
number: action.payload.number + 10
};
default:
return state;
}
};
以上就是一個 Redux 同步資料流的處理,基本上這樣子就是一個簡單又完整在 React 中使用 Redux 管理共同 state 的方式。
而最後 redux 好朋友還偷偷告訴我們一個秘訣,為了讓 lint 工具方便檢查到錯誤,以及讓開發團隊可以更好了解使用了哪些 action types 的時候,這邊透過新增一個 action-types 的檔案來管理。
方式很簡單,將所有目前使用到的 action 都在 action-types 集中管理,並透過匯出的方式在 React 元件、 Redux 中使用。
相關測試範例,點擊前往
在 action-types 這隻檔案中會看到這樣子的管理:
export const INCREMENTHANDLER = "INCREMENTHANDLER";
export const DECREMENTHANDLER = "DECREMENTHANDLER";
export const INCREMENTTENNUMBERHANDLER = "INCREMENTTENNUMBERHANDLER";
在 rootReducer 中則會改寫如下:
import * as actionTypes from './action-types';
const initialState = {
number: 0
};
export const rootReducer = (state = initialState, action) => {
switch (action.type) {
case actionTypes.INCREMENTHANDLER:
return {
number: state.number + 1
};
case actionTypes.DECREMENTHANDLER:
return {
number: state.number - 1
};
case actionTypes.INCREMENTTENNUMBERHANDLER:
return {
number: action.payload.number + 10
};
default:
return state;
}
};
在 App.js 中則會改寫如下:
import React, { Component } from "react";
import { connect } from "react-redux";
import * as actionTypes from "./store/action-types";
import "./styles.css";
class App extends Component {
render() {
return (
<div className="App">
<h2>數字: {this.props.number}</h2>
<button onClick={this.props.incrementHandler}>點擊 + 1</button>
<button onClick={this.props.decrementHandler}>點擊 - 1</button>
<button
onClick={() => {
this.props.incrementTenNumberHandler(this.props.number);
}}
>
由當前數字 + 10
</button>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
number: state.number
};
};
const mapDispatchToProps = (dispatch) => {
return {
incrementHandler: () => dispatch({ type: actionTypes.INCREMENTHANDLER }),
decrementHandler: () => dispatch({ type: actionTypes.DECREMENTHANDLER }),
incrementTenNumberHandler: (number) =>
dispatch({
type: actionTypes.INCREMENTTENNUMBERHANDLER,
payload: {
number
}
})
};
};
export default connect(mapStateToProps, mapDispatchToProps)(App);
所以當我們在 dispatch 一個 action 時如果有拼寫不對等等的錯誤時,可以得到類似以下的錯誤訊息:
透過 lint 等工具可以讓我們更快知道問題發生的位置。
以上就是 Redux 好朋友在今天跟我們分享的部分,但是它冷冷的補了一句:「你以為結束了嗎? 不,這其實剛開始...」。
於是明天要進入的是 Redux 的另外一個重點: 非同步資料流。
鐵人賽文章與程式碼同步發佈於:
我們明天見。