您好,登錄后才能下訂單哦!
本文實例為大家分享了react用Redux中央倉庫實現一個todolist的具體代碼,供大家參考,具體內容如下
Redux簡單介紹
Redux是一個用來管理管理數據狀態和UI狀態的JavaScript應用工具。隨著JavaScript單頁應用(SPA)開發日趨復雜,JavaScript需要管理比任何時候都要多的state(狀態),Redux就是降低管理難度的。(Redux支持React,Angular、jQuery甚至純JavaScript)
Redux Dev Tools插件 Redux調試工具 谷歌商店下載
redux三個坑:
store倉庫必須是唯一的,多個store是堅決不允許,只能有一個store空間
只有store能改變自己的內容,Reducer不能改變
Reducer必須是純函數
Redux-thunk這個Redux最常用的插件:
在Dispatch一個Action之后,到達reducer之前,進行一些額外的操作,就需要用到middleware(中間件)
在實際工作中你可以使用中間件來進行日志記錄、創建崩潰報告,調用異步接口或者路由
npm install --save redux-thunk
第一步 倉庫 在store文件夾下新建index.js
//applyMiddleware,compose是為了使用下面兩個插件 import {createStore,applyMiddleware,compose} from 'redux' //引入redux import thunk from 'redux-thunk' //引入redux中間件插件 import reducer from './reducer' //引用reducer中的數據 //瀏覽器安裝的倉庫插件 調試面板 const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}):compose //redux中間件插件 此函數為了兼容兩個插件并行 const enhancer = composeEnhancers(applyMiddleware(thunk)) //定義一個倉庫 唯一的 不能有兩個倉庫 createStore倉庫只接收兩個參數 const store = createStore( reducer, enhancer) // 創建數據存儲倉庫 export default store //將倉庫導出
新建reducer.js 做倉庫數據處理
import {ADD_ITEM , DELETE_ITEM , GET_LIST} from './actionTypes' //定義type類型的js文件 const defaultState = { value:'sss', list:[] //后端獲取的列表數據放在這里 } // state: 指的是原始倉庫里的狀態。 // action: 指的是action新傳遞的狀態。 export default (state = defaultState,action)=>{ // console.log(state) //Reducer里只能接收state 不能改變state // if(action.type ==="changeInput"){ // let newState = JSON.parse(JSON.stringify(state)) //深拷貝state的值 轉成字符串 賦值給一個變量 // newState.value = action.vlaue //改變placeholder的值等于用戶輸入的值 // return newState //將新state return出去 // } //增加 if(action.type === ADD_ITEM ){ //根據type值,編寫業務邏輯 let newState = JSON.parse(JSON.stringify(state)) newState.list.push(action.value) //用戶輸入的新內容push新的內容到列表中去 console.log(action) newState.value = '' //增加后清空 return newState } //刪除 if(action.type === DELETE_ITEM ){ let newState = JSON.parse(JSON.stringify(state)) newState.list.splice(action.index,1) //刪除數組中對應的值 return newState } //后端獲取數據 傳遞給中央倉庫做處理 if(action.type === GET_LIST ){ let newState = JSON.parse(JSON.stringify(state)) newState.list =action.data return newState } return state }
actionTypes.js 集中管理頁面reducer的type類型
//集中管理頁面reducer的type類型 export const ADD_ITEM = "addItem" //定義常量一般用大寫 export const DELETE_ITEM = "deleteItem" export const GET_LIST = "getListAction"
actionCreators.js 封裝組件的action
//封裝組件的action import {ADD_ITEM , DELETE_ITEM ,GET_LIST} from './actionTypes' //定義type類型的js import axios from 'axios' //組件addItem里的action type已經封好 所以把value作為參數用箭頭函數(value)=>傳進來即可 //增加數據 export const addItem = (value)=>({ type:ADD_ITEM, value }) //刪除數據 export const deleteItem = (index)=>({ type:DELETE_ITEM, index }) //獲取數據 export const getListAction = (data)=>({ type:GET_LIST, data }) export const getTodoList = () =>{ return (dispatch)=>{ axios.get('https://www.easy-mock.com/mock/5d63d7ca5774121e1a634378/demo1/demo1') .then((res)=> { const data = res.data.data; const action = getListAction(data) dispatch(action) //將action這個值傳給倉庫 }) .catch((error)=>{ console.log(error) }) } }
TodoList.js 組件js部分
import React, { Component } from 'react'; import TodoListUi from './TodoListUi' //組件UI部分 import store from '../store/index' //組件中獲得store中的數據 //import {ADD_ITEM , DELETE_ITEM} from '../store/actionTypes' //定義type類型的js 為了更方便檢查錯誤 寫錯會報錯 import { addItem,deleteItem,getTodoList } from '../store/actionCreators' //封裝的action //用reducer寫todolist 調用中央倉庫 class TodoList extends Component { constructor(props){ super(props) // console.log(store.getState()) //getState方法取出倉庫的值 this.state = store.getState() //將組件state數據賦值給倉庫數據 this.changeInputVlaue = this.changeInputVlaue.bind(this) //給方法做this綁定 this.storeChange = this.storeChange.bind(this) this.clickBtn = this.clickBtn.bind(this) this.deleteItem = this.deleteItem.bind(this) store.subscribe(this.storeChange) //訂閱模式 改變數據時同步讓倉庫中的數據改變 } render() { return ( <TodoListUi value={this.state.value} changeInputVlaue={this.changeInputVlaue} clickBtn={this.clickBtn} list={this.state.list} deleteItem = {this.deleteItem} ></TodoListUi> ); } componentDidMount(){ // axios.get('https://www.easy-mock.com/mock/5d63d7ca5774121e1a634378/demo1/demo1') // .then((res)=> // { // const data = res.data.data; // const action =getListAction(data) //將取到的數據封入action // store.dispatch(action) //傳遞給reducer // }) // .catch((error)=>{ // console.log(error) // }) const action = getTodoList() //使用中間件獲取數據 store.dispatch(action) //傳給倉庫 } //用戶輸入的值傳給倉庫 要通過dispatch()方法傳遞給store //Action就是一個對象,這個對象一般有兩個屬性,第一個是對Action的描述,第二個是要改變的值。 //之前注銷的方法,在reducer里深拷貝完state里面的數據,無法同步將用戶輸入賦值給state changeInputVlaue(e){ this.setState({ value:e.target.value //將用戶輸入的value綁定給倉庫中的value,監聽用戶輸入 }) // const action = { // type:'changeInput', // 名字 // value:e.target.value //值 // } // store.dispatch(action) } //state和組件的值同步互相改變 storeChange(){ this.setState(store.getState()) } //增加 因為list數據存在中央倉庫里 所以要做的是 將組件數據傳給倉庫 改變倉庫數據后 再返回給組件展示 clickBtn(){ // console.log(this.state.value) // const action = { // type:ADD_ITEM, // value:this.state.value //獲取到用戶value,用于push // } const action = addItem(this.state.value); store.dispatch(action) } //刪除 deleteItem(index){ // console.log(index) // const action = { // type:DELETE_ITEM, // index //index傳過去用于刪除 // } const action =deleteItem(index) store.dispatch(action) } } export default TodoList;
TodoListUi.js 組件UI部分抽離成子組件
//此文件用于視圖和邏輯的分離 import React from 'react'; import 'antd/dist/antd.css' //引入Ant Design UI庫 import { Input ,Button,List} from 'antd' //引入input組件 //無狀態組件 提高性能 將組件改造成函數 const TodoListUi = (props)=>{ return ( <div style={{margin:"100px"}}> <div> <Input style={{ width:"250px",marginRight:"20px"}} onChange={props.changeInputVlaue} value={props.value} /> <Button type='primary' onClick={props.clickBtn}>增加</Button> </div> <div style={{margin:"10px",width:"300px"}}> <List bordered //加邊框 dataSource={props.list} //渲染什么數據 renderItem={(item,index)=>(<List.Item onClick={()=>{props.deleteItem(index)}}>{item}</List.Item>)} //每項 /> </div> </div> ); } //改造前組件 上邊需要從react引入Component // class TodoListUi extends Component { // state = { } // render() { // return ( // <div style={{margin:"100px"}}> // <div> // <Input // style={{ width:"250px",marginRight:"20px"}} // onChange={this.props.changeInputVlaue} // value={this.props.value} // /> // <Button type='primary' onClick={this.props.clickBtn}>增加</Button> // </div> // <div style={{margin:"10px",width:"300px"}}> // <List // bordered //加邊框 // dataSource={this.props.list} //渲染什么數據 // renderItem={(item,index)=>(<List.Item onClick={()=>{this.props.deleteItem(index)}}>{item}</List.Item>)} //每項 // /> // </div> // </div> // ); // } // } export default TodoListUi;
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。