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

react+redux的升級版todoList的實(shí)現(xiàn)

 更新時間:2017年12月18日 08:38:33   作者:簡心豆  
本篇文章主要介紹了react+redux的升級版todoList的實(shí)現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

又是很久不寫博客了,最近在用螞蟻金服的ant-design-pro寫畢設(shè),寫著寫著寫不下去了,很多東西都不理解,不得不說大神寫出來的東西都是需要花學(xué)習(xí)成本的,或者底子好,對于React新手來說就有點(diǎn)難了。所以就老老實(shí)實(shí)的認(rèn)真看了下Redux到底如何使用,在這里推薦一下自己最近在看的書,寫的算是比較詳細(xì)的:《深入React技術(shù)?!贰U話不多說,今天就分享下自己如何使用redux來實(shí)現(xiàn)一個todoList的,希望對想要用redux的你會有所幫助。

(為什么叫升級版呢?因?yàn)橹皩戇^一個沒有用redux的todoList

該項(xiàng)目使用react官方的create-react-app架構(gòu),每個目錄可以根據(jù)自己的需求來劃分。下面解釋下每個目錄的內(nèi)容和功能。

public:主要放靜態(tài)資源(入口html文件,圖片資源,JSON文件等);

src/component:不同的組件;

src/layouts:整個頁面的基本架構(gòu),主要就是Nav,F(xiàn)ooter,Content。Nav里面顯示User和Notice的數(shù)據(jù),Content中實(shí)現(xiàn)頁面路由的切換,F(xiàn)ooter固定不變;

src/redux:

--src/redux/configureStore:生成整個應(yīng)用的store;

--src/redux/reducers:所有reducer的集合;

src/routes:頁面的整體路由;

src/utils:自己封裝的工具;

views:存放項(xiàng)目中所要展示的所有頁面;

index:整個項(xiàng)目的入口文件;

二. 具體實(shí)現(xiàn)

1. 整個應(yīng)用中store中應(yīng)存儲什么數(shù)據(jù)?

const initialState = {
  taskListData: { //任務(wù)列表
    loading: false,
    error: false,
    taskList: [],
  }, 
  userData: { //用戶信息
    loading: false,
    error: false,
    user: {},
  },
  noticeListData: { //通知列表
    loading: false,
    error: false,
    noticeList: [],
  },
  taskData: { //任務(wù)詳情,在詳情頁使用
    loading: false,
    error: false,
    task: {},
  }
};

2. reducer的分布:

每個state對應(yīng)一個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都對應(yīng)一個reducer,所以和state一樣,reducer應(yīng)在放在最頂級的父級組件的目錄中,所以將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由組件發(fā)出,所以將action creator單獨(dú)一個文件,放在組件目錄中。例如:ListItem組件的action creator:

/*ListItem/indexRedux.js*/
//處理更新任務(wù)狀態(tài)后和刪除任務(wù)后的taskList的狀態(tài);
const UPDATE_TASK = 'UPDATE_TASK';
const DELETE_TASK = 'DELETE_TASK';
//action creator,更新和刪除任務(wù)
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綁在組件上,然后在組價內(nèi)部以props的方式獲取。下面是TodoList頁面的具體實(shí)現(xiàn):

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方法有四個參數(shù),這里主要說下前兩個參數(shù):

(1)mapStateToProps:參數(shù)為state,返回頁面所需要的所有state;

(2)mapDispatchToProps:參數(shù)為dispatch,返回頁面所要使用的異步回調(diào)函數(shù)。

眼明手快的你肯定看到了,我們從redux包中導(dǎo)出了bindActionCreators方法,該方法將dispatch和action creator綁定,用來觸發(fā)action。

四. 異步的action creator如何觸發(fā)呢?

因?yàn)槊總€action creator都是異步函數(shù),我們傳給組件的只是函數(shù)的聲明,所以就要引入我們的中間件,只用在生成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在整個應(yīng)用中都存在,所以應(yīng)該在整個應(yīng)用的最頂層,對于一般項(xiàng)目而言,當(dāng)然就是最頂端的路由了:

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傳入整個應(yīng)用。

基本要講的就是這些內(nèi)容,完整的項(xiàng)目請看 github
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • React Native實(shí)現(xiàn)進(jìn)度條彈框的示例代碼

    React Native實(shí)現(xiàn)進(jìn)度條彈框的示例代碼

    本篇文章主要介紹了React Native實(shí)現(xiàn)進(jìn)度條彈框的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • create-react-app構(gòu)建項(xiàng)目慢的解決方法

    create-react-app構(gòu)建項(xiàng)目慢的解決方法

    這篇文章主要介紹了create-react-app構(gòu)建項(xiàng)目慢的解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • React Native中TabBarIOS的簡單使用方法示例

    React Native中TabBarIOS的簡單使用方法示例

    最近在學(xué)習(xí)過程中遇到了很多問題,TabBarIOS的使用就是一個,所以下面這篇文章主要給大家介紹了關(guān)于React Native中TabBarIOS簡單使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。
    2017-10-10
  • react實(shí)現(xiàn)Modal彈窗效果

    react實(shí)現(xiàn)Modal彈窗效果

    這篇文章主要為大家詳細(xì)介紹了react實(shí)現(xiàn)Modal彈窗效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • styled-components?性能詳解

    styled-components?性能詳解

    這篇文章主要為大家介紹了styled-components?的性能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • React中使用echarts-for-react的方法示例

    React中使用echarts-for-react的方法示例

    echarts-for-react則是ECharts在React生態(tài)中的官方封裝組件,它讓開發(fā)者能夠輕松地在React應(yīng)用中集成ECharts圖表,本文就來介紹一下echarts-for-react的使用,感興趣的可以了解一下
    2025-03-03
  • Remix如何支持原生?CSS方法詳解

    Remix如何支持原生?CSS方法詳解

    這篇文章主要為大家介紹了Remix如何支持原生CSS的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • 深入解析React?Hooks?閉包陷阱

    深入解析React?Hooks?閉包陷阱

    這篇文章主要為大家介紹了React Hooks閉包陷阱的深入探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • ReactNative中使用Redux架構(gòu)總結(jié)

    ReactNative中使用Redux架構(gòu)總結(jié)

    本篇文章主要介紹了ReactNative中使用Redux架構(gòu)總結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • React中的Props類型校驗(yàn)和默認(rèn)值詳解

    React中的Props類型校驗(yàn)和默認(rèn)值詳解

    這篇文章主要為大家詳細(xì)介紹了React中的Props類型校驗(yàn)和默認(rèn)值,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03

最新評論

南和县| 磐石市| 密山市| 云浮市| 廊坊市| 上杭县| 延寿县| 津南区| 永善县| 岑溪市| 万宁市| 建阳市| 吴桥县| 得荣县| 泗阳县| 靖州| 平定县| 扎囊县| 岳西县| 西贡区| 淅川县| 安吉县| 岱山县| 新巴尔虎左旗| 乐业县| 县级市| 宁都县| 葵青区| 木兰县| 独山县| 涿鹿县| 孝昌县| 谢通门县| 昆山市| 安陆市| 石城县| 北流市| 石河子市| 康定县| 南木林县| 甘南县|