如何透過react+redux升級版來實現todoList
這篇文章主要介紹了react redux的升級版todoList的實現,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧
又是很久不寫博客了,最近在用螞蟻金服的ant-design-pro寫畢設,寫著寫著寫不下去了,很多東西都不理解,我不得不說大神寫出來的東西都是需要花學習成本的,或是底子好,對於React新手來說就有點難了。所以就老老實實的認真看了下Redux到底如何使用,在這裡推薦一下自己最近在看的書,寫的算是比較詳細的:《深入React技術棧》。廢話不多說,今天就分享下自己如何使用redux來實現一個todoList的,希望對想要用redux的你會有所幫助。
(為什麼叫升級版呢?因為之前寫過一個沒有用redux的todoList)
該項目使用react官方的create-react-app架構,每個目錄可以依照自己的需求來劃分。下面解釋下每個目錄的內容和功能。
public:主要放靜態資源(入口html文件,圖片資源,JSON檔案等);
src/component:不同的元件;
src/layouts:整個頁面的基本架構,主要是Nav,Footer,Content。 Nav裡面顯示User和Notice的數據,Content中實作頁面路由的切換,Footer固定不變;
src/redux:
--src/redux/configureStore:產生整個應用的store;
--src/redux/reducers:所有reducer的集合;
src/routes:頁面的整體路由;
src/utils:自己封裝的工具;
views:存放專案中所要展示的所有頁面;
index:整個專案的入口檔案;
二. 具體實作
1. 整個應用程式中store應儲存哪些資料?
const initialState = { taskListData: { //任务列表 loading: false, error: false, taskList: [], }, userData: { //用户信息 loading: false, error: false, user: {}, }, noticeListData: { //通知列表 loading: false, error: false, noticeList: [], }, taskData: { //任务详情,在详情页使用 loading: false, error: false, task: {}, } };
2. reducer的分佈:
每個state對應一個reducer,所以一共需要四個reducer,在src/redux/reducers中將所有的reducer合併,並且注意每個reducer的名字要和state同名:
/*redux/reducers.js*/ import { combineReducers } from 'redux'; import userReducer from '../component/User/indexRedux'; import noticeReducer from '../component/Notice/indexRedux'; import todoListReducer from '../views/TodoList/indexRedux'; import taskReducer from '../views/Detail/indexRedux'; export default combineReducers({ userData: userReducer, noticeListData: noticeReducer, taskListData: todoListReducer, taskData: taskReducer, });
每個state都對應一個reducer,所以和state一樣,reducer應該在放在最頂級的父級組件的目錄中,所以將taskListData的reducer放在src/views/TodoList中,其他同理,程式碼如下:
/*views/TodoList/indexRedux.js*/ const taskListData = { loading: true, error: false, taskList: [] }; //不同的action; const LOAD_TASKLIST = 'LOAD_TASKLIST'; const LOAD_TASKLIST_SUCCESS = 'LOAD_TASKLIST_SUCCESS'; const LOAD_TASKLIST_ERROR = 'LOAD_TASKLIST_ERROR'; const ADD_TASK = 'ADD_TASK'; const UPDATE_TASK = 'UPDATE_TASK'; const DELETE_TASK = 'DELETE_TASK'; function todoListReducer (state = { taskListData }, action) { switch(action.type) { case LOAD_TASKLIST: { return { ...state, loading: true, error: false, } } case LOAD_TASKLIST_SUCCESS: { return { ...state, loading: false, error: false, taskList: action.payload, }; } case LOAD_TASKLIST_ERROR: { return { ...state, loading: false, error: true }; } case UPDATE_TASK: { const index = state.taskList.indexOf( state.taskList.find(task => task.id === action.payload.id)); console.log(index); state.taskList[index].status = !state.taskList[index].status; return { ...state, taskList: state.taskList, }; } case DELETE_TASK: { const index = state.taskList.indexOf( state.taskList.find(task => task.id === action.payload.id)); state.taskList.splice(index, 1); return { ...state, taskList: state.taskList, }; } case ADD_TASK: { let len = state.taskList.length; let index = len > 0 ? len - 1 : 0; let lastTaskId = index !== 0 ? state.taskList[index].id : 0; state.taskList.push({ id: lastTaskId + 1, name: action.payload.name, status: false, }); return { ...state, taskList: state.taskList, } } default: { return state; } } } export default todoListReducer;
3. action creator的分佈:
每個動作都代表一個action,action由元件發出,所以將action creator單獨一個文件,放在元件目錄中。例如:ListItem元件的action creator:
/*ListItem/indexRedux.js*/ //处理更新任务状态后和删除任务后的taskList的状态; const UPDATE_TASK = 'UPDATE_TASK'; const DELETE_TASK = 'DELETE_TASK'; //action creator,更新和删除任务 export function updateTask (task) { return dispatch => { dispatch({ type: UPDATE_TASK, payload: task, }); } } export function deleteTask (task) { return dispatch => { dispatch({ type: DELETE_TASK, payload: task, }); } }
三. 如何將redux和元件連接
react-redux提供了connect方法,將state和action creator綁在元件上,然後在組價內部以props的方式取得。以下是TodoList頁面的具體實作:
import React, { Component } from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import List from '../../component/List'; import { loadTaskList } from '../../component/List/indexRedux'; import { updateTask, deleteTask } from '../../component/ListItem/indexRedux'; import { addTask } from '../../component/SubmitDialog/indexRedux'; class TodoList extends Component { render () { return ( <List {...this.props} /> ); } } export default connect( state => { return { loading: state.taskListData.loading, error: state.taskListData.error, taskList: state.taskListData.taskList, }; }, dispatch => { return { loadTaskList: bindActionCreators(loadTaskList, dispatch), updateTask: bindActionCreators(updateTask, dispatch), deleteTask: bindActionCreators(deleteTask, dispatch), addTask: bindActionCreators(addTask, dispatch), }; })(TodoList);
connect方法有四個參數,這裡主要說下前兩個參數:
(1)mapStateToProps:參數為state,回傳頁面所需要的所有state;
(2)mapDispatchToProps:參數為dispatch,傳回頁面所要使用的非同步回呼函數。
眼明手快的你肯定看到了,我們從redux套件中導出了bindActionCreators方法,該方法將dispatch和action creator綁定,用來觸發action。
四. 非同步的action creator如何觸發呢?
因為每個action creator都是非同步函數,我們傳給元件的只是函數的聲明,所以就要引入我們的中間件,只用在生成store時加入就行了:
/*redux/configureStore.js*/ import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import reducers from './reducers'; const initialState = { taskListData: { loading: false, error: false, taskList: [], }, userData: { loading: false, error: false, user: {}, }, noticeListData: { loading: false, error: false, noticeList: [], }, taskData: { loading: false, error: false, task: {}, } }; let enhancer = applyMiddleware(thunk); let store = createStore( reducers, initialState, enhancer, ); export default store;
在上面的程式碼中thunk就是一個中間件,我們將引入的中間件傳入applyMiddleware就可以了。
五. store在哪裡傳入元件呢?
我們一定會想到,store在整個應用程式中都存在,所以應該在整個應用程式的最頂層,對於一般專案而言,當然就是最頂端的路由了:
import React, { Component } from 'react'; import { BrowserRouter as Router, Route } from 'react-router-dom'; import { Provider } from 'react-redux'; import BasicLayout from '../layouts'; import store from '../redux/configureStore'; class RouterApp extends Component { render () { return ( <Provider store={store}> <Router> <Route path="/" component={BasicLayout} /> </Router> </Provider> ); } } export default RouterApp;
Provider是react-redux的一個元件,作用就是用來將store傳入整個應用程式。
上面是我整理給大家的,希望今後對大家有幫助。
相關文章:
#Chrome Firefox 自帶偵錯工具偵錯(詳細教學)
以上是如何透過react+redux升級版來實現todoList的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

React前後端分離指南:如何實現前後端的解耦和獨立部署,需要具體程式碼範例在當今的Web開發環境中,前後端分離已經成為一種趨勢。透過將前端和後端程式碼分開,可以讓開發工作更加靈活、高效,並且方便進行團隊協作。本文將介紹如何使用React實現前後端分離,從而實現解耦和獨立部署的目標。首先,我們要先理解什麼是前後端分離。傳統的Web開發模式中,前端和後端是耦合在

如何利用React和RabbitMQ建立可靠的訊息傳遞應用程式引言:現代化的應用程式需要支援可靠的訊息傳遞,以實現即時更新和資料同步等功能。 React是一種流行的JavaScript庫,用於建立使用者介面,而RabbitMQ是一種可靠的訊息傳遞中間件。本文將介紹如何結合React和RabbitMQ建立可靠的訊息傳遞應用,並提供具體的程式碼範例。 RabbitMQ概述:

ReactRouter使用指南:如何實現前端路由控制隨著單頁應用的流行,前端路由成為了一個不可忽視的重要部分。 ReactRouter作為React生態系統中最受歡迎的路由庫,提供了豐富的功能和易用的API,使得前端路由的實作變得非常簡單和靈活。本文將介紹ReactRouter的使用方法,並提供一些具體的程式碼範例。安裝ReactRouter首先,我們需要

PHP、Vue和React:如何選擇最適合的前端框架?隨著互聯網技術的不斷發展,前端框架在Web開發中起著至關重要的作用。 PHP、Vue和React作為三種代表性的前端框架,每一種都具有其獨特的特徵和優勢。在選擇使用哪種前端框架時,開發人員需要根據專案需求、團隊技能和個人偏好做出明智的決策。本文將透過比較PHP、Vue和React這三種前端框架的特徵和使

Java框架與React框架的整合:步驟:設定後端Java框架。建立專案結構。配置建置工具。建立React應用程式。編寫RESTAPI端點。配置通訊機制。實戰案例(SpringBoot+React):Java程式碼:定義RESTfulAPI控制器。 React程式碼:取得並顯示API回傳的資料。

如何利用React開發一個響應式的後台管理系統隨著互聯網的快速發展,越來越多的企業和組織需要一個高效、靈活、易於管理的後台管理系統來處理日常的操作事務。 React作為目前最受歡迎的JavaScript庫之一,提供了一種簡潔、高效和可維護的方式來建立使用者介面。本文將介紹如何利用React開發一個響應式的後台管理系統,並給出具體的程式碼範例。建立React專案首先

Vue.js適合中小型項目和快速迭代,React適用於大型複雜應用。 1)Vue.js易於上手,適用於團隊經驗不足或項目規模較小的情況。 2)React的生態系統更豐富,適合有高性能需求和復雜功能需求的項目。

react有事件處理函數、useEffect和useCallback、高階元件等等閉包。詳細介紹:1、事件處理函數閉包:在React中,當我們在元件中定義事件處理函數時,函數會形成一個閉包,可以存取元件作用域內的狀態和屬性。這樣可以在事件處理函數中使用元件的狀態和屬性,實現互動邏輯;2、useEffect和useCallback中的閉包等等。
