七十九、TodoList示例 深入Redux的工作流
2020/11/20、 週五、今天又是奮鬥的一天。 |
@Author:Runsen
React,也有了自己去構建一些應用的信心,那會是一種非常棒的感覺。你學會了管理狀態,一切看起來井井有條。但是,很有可能這就到了你該學習 Redux 的時候了。
Redux-devtools外掛
Redux DevTools是一個開源專案,是為谷歌瀏覽器使用者打造的一款實用除錯外掛,主要適用於開發者使用,使用該外掛可以有效地對應用程式或者網頁的狀態進行除錯操作。
我上傳到CSDN,下載連結:https://download.csdn.net/download/weixin_44510615/13130629
因為我是window系統, 需要新增window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
Redux
原理:React首先改變store裡面的資料state,先要開發一個Aciton,然後通過dispath方法傳遞給store,store再把之前的資料和Action轉化的資料在Reducers進行判斷和對比,Reducers本身就是一個函式,返回新的state,store就替換之前的state。
下面舉新增點選的Redux的工作流流程。
具體程式碼
TodoList.js
import React, {Component } from 'react'
import 'antd/dist/antd.css'
import { Input,Button, List } from 'antd';
// import store from './store'相當於匯入store/index,js
import store from './store';
class TodoList extends Component {
constructor(props) {
super(props)
this.state = store.getState()
this.handleInputChange = this.handleInputChange.bind(this)
this.handleStoreChange = this.handleStoreChange.bind(this)
this.handleBtnClick = this.handleBtnClick.bind(this)
store.subscribe(this.handleStoreChange);
console.log( this.state)
}
render() {
return(
<div>
<div>
<Input
value={this.state.inputValue}
placeholder="Todo info"
style={{width:'300px',marginRight:'10px' }}
onChange={this.handleInputChange}></Input>
<Button type="primary"
onClick={this.handleBtnClick}>提交</Button>
</div>
<List
bordered
style={{width:'300px',marginTop:'10px' }}
dataSource={this.state.list}
renderItem={(item,index) => (
<List.Item onClick={this.handleItemDelete.bind(this,index)}>
{item}
</List.Item>
)}
/>
</div>
)
}
handleInputChange(e) {
const action = {
type: 'change_input_value',
value: e.target.value
}
store.dispatch(action)
}
handleStoreChange() {
this.setState(store.getState());
}
handleBtnClick() {
const action = {
type: 'add_todo_item',
}
store.dispatch(action)
}
handleItemDelete(index) {
const action = {
type: 'delete_todo_item',
index
}
store.dispatch(action)
}
}
export default TodoList;
reducer.js
/* eslint-disable import/no-anonymous-default-export */
const defaultState = {
inputValue : '123',
list: [1,2]
}
export default (state = defaultState , action) => {
if (action.type === 'change_input_value'){
const newState = JSON.parse(JSON.stringify(state));
newState.inputValue = action.value
return newState
}
if (action.type === 'add_todo_item'){
const newState = JSON.parse(JSON.stringify(state));
newState.list.push(newState.inputValue)
newState.inputValue ='';
return newState
}
if (action.type === 'delete_todo_item'){
const newState = JSON.parse(JSON.stringify(state));
newState.list.splice(action.inbdex,1)
return newState
}
return state;
}
index.js
import { createStore } from 'redux';
import reducer from './reducer';
const store = createStore(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
export default store;
ActionTypes和ActionCreator拆分
由於全部程式碼在TodoList.js寫死了,不容易維護,需要進行ActionTypes和ActionCreator拆分
具體目錄如下
TodoList.js
import React, {Component } from 'react'
import 'antd/dist/antd.css'
import { Input,Button, List } from 'antd';
// import store from './store'相當於匯入store/index,js
import store from './store';
import { getInitList, getInputChangeAction, getAddItemAction, getDeleteItemAction } from './store/actionCreators'
class TodoList extends Component {
constructor(props) {
super(props)
this.state = store.getState()
this.handleInputChange = this.handleInputChange.bind(this)
this.handleStoreChange = this.handleStoreChange.bind(this)
this.handleBtnClick = this.handleBtnClick.bind(this)
store.subscribe(this.handleStoreChange);
console.log( this.state)
}
render() {
return(
<div>
<div>
<Input
value={this.state.inputValue}
placeholder="Todo info"
style={{width:'300px',marginRight:'10px' }}
onChange={this.handleInputChange}></Input>
<Button type="primary"
onClick={this.handleBtnClick}>提交</Button>
</div>
<List
bordered
style={{width:'300px',marginTop:'10px' }}
dataSource={this.state.list}
renderItem={(item,index) => (
<List.Item onClick={this.handleItemDelete.bind(this,index)}>
{item}
</List.Item>
)}
/>
</div>
)
}
componentDidMount() {
const action = getInitList();
store.dispatch(action);
}
handleInputChange(e) {
const action = getInputChangeAction(e.target.value);
store.dispatch(action);
}
handleStoreChange() {
this.setState(store.getState());
}
handleBtnClick() {
const action = getAddItemAction();
store.dispatch(action);
}
handleItemDelete(index) {
const action = getDeleteItemAction(index);
store.dispatch(action);
}
}
export default TodoList;
actionCreators.js
import { GET_INIT_LIST, CHANGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM, INIT_LIST_ACTION } from './actionTypes';
export const getInputChangeAction = (value) => ({
type: CHANGE_INPUT_VALUE,
value
});
export const getAddItemAction = () => ({
type: ADD_TODO_ITEM
});
export const getDeleteItemAction = (index) => ({
type: DELETE_TODO_ITEM,
index
});
export const initListAction = (data) => ({
type: INIT_LIST_ACTION,
data
});
export const getInitList = () => ({
type: GET_INIT_LIST
});
actionTypes.js
export const CHANGE_INPUT_VALUE = 'change_input_value';
export const ADD_TODO_ITEM = 'add_todo_item';
export const DELETE_TODO_ITEM = 'delete_todo_item';
export const INIT_LIST_ACTION = 'init_list_action';
export const GET_INIT_LIST = 'get_init_list';
reducer.js
import { INIT_LIST_ACTION, CHANGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM } from './actionTypes'
const defaultState = {
inputValue: '',
list: []
}
// reducer 可以接受state,但是絕不能修改state
// 純函式指的是,給定固定的輸入,就一定會有固定的輸出,而且不會有任何副作用
export default (state = defaultState, action) => {
if (action.type === CHANGE_INPUT_VALUE) {
const newState = JSON.parse(JSON.stringify(state));
newState.inputValue = action.value;
return newState;
}
if (action.type === INIT_LIST_ACTION) {
const newState = JSON.parse(JSON.stringify(state));
newState.list = action.data;
return newState;
}
if (action.type === ADD_TODO_ITEM) {
const newState = JSON.parse(JSON.stringify(state));
newState.list.push(newState.inputValue);
newState.inputValue = '';
return newState;
}
if (action.type === DELETE_TODO_ITEM) {
const newState = JSON.parse(JSON.stringify(state));
newState.list.splice(action.index, 1);
return newState;
}
return state;
}
相關文章
- 通過 todoList 搞懂 reduxRedux
- Redux 入門 Demo:TodoListRedux
- TodoList深入Flutter狀態管理(上篇)Flutter
- 深入理解reduxRedux
- 深入理解redux之從redux原始碼到react-redux的原理Redux原始碼React
- 深入淺出理解ReduxRedux
- 基於 Redux + Redux Persist 進行狀態管理的 Flutter 應用示例ReduxFlutter
- 深入工作流排程的核心
- 深入淺出redux學習Redux
- 深入淺出redux-middlewareRedux
- 深入淺出React和ReduxReactRedux
- 深入學習和理解 ReduxRedux
- todolist
- 五分鐘帶你回顧Redux工作流Redux
- 深入理解 Redux 中介軟體Redux
- 工作流引擎Activiti使用進階!詳細解析工作流框架中高階功能的使用示例框架
- Taro-library:Taro + Redux + 本地 Mock Server 示例專案ReduxMockServer
- redux深入理解之中介軟體(middleware)Redux
- Vue-todolistVue
- Vue 案例:ToDoListVue
- 通過GitHub Blame深入分析Redux原始碼GithubRedux原始碼
- 前端筆記之React(五)Redux深入淺出前端筆記ReactRedux
- 深入理解 ES Modules (手繪示例)
- Vue版todolist案例Vue
- 學習 redux 原始碼整體架構,深入理解 redux 及其中介軟體原理Redux原始碼架構
- React + Antd實現簡單的todolistReact
- 小程式TodoList實踐
- React 系列一 之 TodoListReact
- 深入理解redux之reducer為什麼是純函式Redux函式
- React Demo Two - TodoList 升級React
- redux的bindActionCreatorsRedux
- 初學微信小程式 TodoList微信小程式
- Vue專案實戰(一)——ToDoListVue
- vue - Vue腳手架/TodoList案例Vue
- Kotlin 布林值教程:深入理解與應用示例Kotlin
- react、redux、react-redux之間的關係ReactRedux
- 更好用的 ReduxRedux
- Flutter實踐:深入 Flutter 的狀態管理方式(3)——旅途小結與Redux實踐FlutterRedux