最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

react用Redux中央倉(cāng)庫(kù)實(shí)現(xiàn)一個(gè)todolist

 更新時(shí)間:2019年09月29日 09:12:50   作者:小羽向前跑  
這篇文章主要為大家詳細(xì)介紹了react用Redux中央倉(cāng)庫(kù)實(shí)現(xiàn)一個(gè)todolist,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了react用Redux中央倉(cāng)庫(kù)實(shí)現(xiàn)一個(gè)todolist的具體代碼,供大家參考,具體內(nèi)容如下

Redux簡(jiǎn)單介紹

Redux是一個(gè)用來(lái)管理管理數(shù)據(jù)狀態(tài)和UI狀態(tài)的JavaScript應(yīng)用工具。隨著JavaScript單頁(yè)應(yīng)用(SPA)開(kāi)發(fā)日趨復(fù)雜,JavaScript需要管理比任何時(shí)候都要多的state(狀態(tài)),Redux就是降低管理難度的。(Redux支持React,Angular、jQuery甚至純JavaScript)

Redux Dev Tools插件 Redux調(diào)試工具 谷歌商店下載

redux三個(gè)坑:

store倉(cāng)庫(kù)必須是唯一的,多個(gè)store是堅(jiān)決不允許,只能有一個(gè)store空間

只有store能改變自己的內(nèi)容,Reducer不能改變

Reducer必須是純函數(shù)

Redux-thunk這個(gè)Redux最常用的插件:

在Dispatch一個(gè)Action之后,到達(dá)reducer之前,進(jìn)行一些額外的操作,就需要用到middleware(中間件)

在實(shí)際工作中你可以使用中間件來(lái)進(jìn)行日志記錄、創(chuàng)建崩潰報(bào)告,調(diào)用異步接口或者路由

npm install --save redux-thunk

第一步 倉(cāng)庫(kù) 在store文件夾下新建index.js

//applyMiddleware,compose是為了使用下面兩個(gè)插件
import {createStore,applyMiddleware,compose} from 'redux' //引入redux
import thunk from 'redux-thunk' //引入redux中間件插件
import reducer from './reducer'  //引用reducer中的數(shù)據(jù)
 
//瀏覽器安裝的倉(cāng)庫(kù)插件 調(diào)試面板
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}):compose
 
//redux中間件插件 此函數(shù)為了兼容兩個(gè)插件并行
const enhancer = composeEnhancers(applyMiddleware(thunk))
 
//定義一個(gè)倉(cāng)庫(kù) 唯一的 不能有兩個(gè)倉(cāng)庫(kù) createStore倉(cāng)庫(kù)只接收兩個(gè)參數(shù)
const store = createStore( reducer, enhancer) // 創(chuàng)建數(shù)據(jù)存儲(chǔ)倉(cāng)庫(kù)
export default store //將倉(cāng)庫(kù)導(dǎo)出

新建reducer.js 做倉(cāng)庫(kù)數(shù)據(jù)處理

import {ADD_ITEM , DELETE_ITEM , GET_LIST} from './actionTypes' //定義type類型的js文件
 
const defaultState = {
  value:'sss',
  list:[]  //后端獲取的列表數(shù)據(jù)放在這里
}
 
// state: 指的是原始倉(cāng)庫(kù)里的狀態(tài)。
// action: 指的是action新傳遞的狀態(tài)。
export default (state = defaultState,action)=>{
  // console.log(state)
  //Reducer里只能接收state 不能改變state
  // if(action.type ==="changeInput"){
  //   let newState = JSON.parse(JSON.stringify(state)) //深拷貝state的值 轉(zhuǎn)成字符串 賦值給一個(gè)變量
  //   newState.value = action.vlaue //改變placeholder的值等于用戶輸入的值
  //   return newState //將新state return出去
  // }
  //增加
  if(action.type === ADD_ITEM ){ //根據(jù)type值,編寫(xiě)業(yè)務(wù)邏輯
    let newState = JSON.parse(JSON.stringify(state)) 
    newState.list.push(action.value) //用戶輸入的新內(nèi)容push新的內(nèi)容到列表中去
    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) //刪除數(shù)組中對(duì)應(yīng)的值
    return newState
  }
 
   //后端獲取數(shù)據(jù) 傳遞給中央倉(cāng)庫(kù)做處理
   if(action.type === GET_LIST ){ 
    let newState = JSON.parse(JSON.stringify(state)) 
    newState.list =action.data
    return newState
  }
  return state
}

actionTypes.js   集中管理頁(yè)面reducer的type類型

//集中管理頁(yè)面reducer的type類型
 
export const ADD_ITEM = "addItem"  //定義常量一般用大寫(xiě)
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已經(jīng)封好 所以把value作為參數(shù)用箭頭函數(shù)(value)=>傳進(jìn)來(lái)即可 
 
//增加數(shù)據(jù)
export const addItem = (value)=>({
  type:ADD_ITEM,
  value
})
 
//刪除數(shù)據(jù)
export const deleteItem = (index)=>({
  type:DELETE_ITEM,
  index
})
 
//獲取數(shù)據(jù)
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這個(gè)值傳給倉(cāng)庫(kù)
    })
    .catch((error)=>{
      console.log(error)
    })
  }
}

TodoList.js  組件js部分

import React, { Component } from 'react';
import TodoListUi from './TodoListUi' //組件UI部分
import store from '../store/index' //組件中獲得store中的數(shù)據(jù)
//import {ADD_ITEM , DELETE_ITEM} from '../store/actionTypes' //定義type類型的js 為了更方便檢查錯(cuò)誤 寫(xiě)錯(cuò)會(huì)報(bào)錯(cuò)
import { addItem,deleteItem,getTodoList } from '../store/actionCreators' //封裝的action
 
 
//用reducer寫(xiě)todolist 調(diào)用中央倉(cāng)庫(kù)
 
class TodoList extends Component {
  constructor(props){
    super(props)
    // console.log(store.getState()) //getState方法取出倉(cāng)庫(kù)的值
    this.state = store.getState() //將組件state數(shù)據(jù)賦值給倉(cāng)庫(kù)數(shù)據(jù)
    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) //訂閱模式 改變數(shù)據(jù)時(shí)同步讓倉(cāng)庫(kù)中的數(shù)據(jù)改變
  }
  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) //將取到的數(shù)據(jù)封入action
    //    store.dispatch(action) //傳遞給reducer
    //   })
    //   .catch((error)=>{
    //     console.log(error)
    //   })
    const action = getTodoList() //使用中間件獲取數(shù)據(jù)
    store.dispatch(action) //傳給倉(cāng)庫(kù)
  }
  //用戶輸入的值傳給倉(cāng)庫(kù) 要通過(guò)dispatch()方法傳遞給store
  //Action就是一個(gè)對(duì)象,這個(gè)對(duì)象一般有兩個(gè)屬性,第一個(gè)是對(duì)Action的描述,第二個(gè)是要改變的值。
  //之前注銷的方法,在reducer里深拷貝完state里面的數(shù)據(jù),無(wú)法同步將用戶輸入賦值給state
  changeInputVlaue(e){
    this.setState({
      value:e.target.value //將用戶輸入的value綁定給倉(cāng)庫(kù)中的value,監(jiān)聽(tīng)用戶輸入
    })
    // const action = {
    //   type:'changeInput', // 名字
    //   value:e.target.value //值
    // }
    // store.dispatch(action)
  }
 
  //state和組件的值同步互相改變
  storeChange(){
    this.setState(store.getState()) 
  }
 
  //增加 因?yàn)閘ist數(shù)據(jù)存在中央倉(cāng)庫(kù)里 所以要做的是 將組件數(shù)據(jù)傳給倉(cāng)庫(kù) 改變倉(cāng)庫(kù)數(shù)據(jù)后 再返回給組件展示
  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傳過(guò)去用于刪除
    // }
    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庫(kù)
import { Input ,Button,List} from 'antd'  //引入input組件
 
//無(wú)狀態(tài)組件 提高性能 將組件改造成函數(shù)
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} //渲染什么數(shù)據(jù)
          renderItem={(item,index)=>(<List.Item onClick={()=>{props.deleteItem(index)}}>{item}</List.Item>)} //每項(xiàng)
        /> 
      </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} //渲染什么數(shù)據(jù)
//             renderItem={(item,index)=>(<List.Item onClick={()=>{this.props.deleteItem(index)}}>{item}</List.Item>)} //每項(xiàng)
//           /> 
//         </div>
//       </div>
//     );
//   }
// }
 
export default TodoListUi;

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • React styled-components設(shè)置組件屬性的方法

    React styled-components設(shè)置組件屬性的方法

    這篇文章主要介紹了styled-components設(shè)置組件屬性的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • React中關(guān)于render()的用法及說(shuō)明

    React中關(guān)于render()的用法及說(shuō)明

    這篇文章主要介紹了React中關(guān)于render()的用法及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 原生實(shí)現(xiàn)一個(gè)react-redux的代碼示例

    原生實(shí)現(xiàn)一個(gè)react-redux的代碼示例

    這篇文章主要介紹了原生實(shí)現(xiàn)一個(gè)react-redux的代碼示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • 詳解react-router-dom v6版本基本使用介紹

    詳解react-router-dom v6版本基本使用介紹

    本文主要介紹了react-router-dom v6版本基本使用介紹,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • React+Typescript項(xiàng)目環(huán)境搭建并使用redux環(huán)境的詳細(xì)過(guò)程

    React+Typescript項(xiàng)目環(huán)境搭建并使用redux環(huán)境的詳細(xì)過(guò)程

    這篇文章主要介紹了React+Typescript項(xiàng)目環(huán)境搭建并使用redux環(huán)境的詳細(xì)過(guò)程,本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • 詳解React中key的作用

    詳解React中key的作用

    這篇文章主要介紹了React中key的作用,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下
    2021-04-04
  • React生命周期函數(shù)圖解介紹

    React生命周期函數(shù)圖解介紹

    生命周期函數(shù)指在某一時(shí)刻組件會(huì)自動(dòng)調(diào)用并執(zhí)行的函數(shù)。React每個(gè)類組件都包含生命周期方法,以便于在運(yùn)行過(guò)程中特定的階段執(zhí)行這些方法
    2022-11-11
  • react-native彈窗封裝的方法

    react-native彈窗封裝的方法

    這篇文章主要為大家詳細(xì)介紹了react-native彈窗封裝的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • react反向代理使用http-proxy-middleware問(wèn)題

    react反向代理使用http-proxy-middleware問(wèn)題

    這篇文章主要介紹了react反向代理使用http-proxy-middleware問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • react如何修改循環(huán)數(shù)組對(duì)象的數(shù)據(jù)

    react如何修改循環(huán)數(shù)組對(duì)象的數(shù)據(jù)

    這篇文章主要介紹了react如何修改循環(huán)數(shù)組對(duì)象的數(shù)據(jù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12

最新評(píng)論

广宗县| 新和县| 巴里| 闻喜县| 黔西县| 桦川县| 旬阳县| 商城县| 宕昌县| 杂多县| 黄浦区| 搜索| 瑞安市| 交城县| 孝感市| 潮州市| 连平县| 右玉县| 开远市| 光山县| 印江| 招远市| 南涧| 全南县| 成都市| 三明市| 德钦县| 民权县| 兴义市| 孝义市| 临沭县| 同德县| 随州市| 白城市| 当涂县| 沙湾县| 正定县| 开封县| 郧西县| 大埔区| 寿光市|