Home  >  Article  >  Web Front-end  >  How to implement todoList through react+redux upgraded version

How to implement todoList through react+redux upgraded version

亚连
亚连Original
2018-06-20 14:09:071613browse

This article mainly introduces the implementation of the upgraded version of todoList in react redux. The editor thinks it is quite good. Now I will share it with you and give it as a reference. Let’s follow the editor and take a look.

I haven’t written a blog for a long time. Recently, I am using Ant Financial’s ant-design-pro to write my final design. I can’t continue writing, and many things are missing. I don’t understand. I have to say that everything written by masters requires learning costs, or a good foundation, which is a bit difficult for React novices. So I took a serious look at how to use Redux. I would like to recommend a book I have been reading recently, which is quite detailed: "In-depth React Technology Stack". Without further ado, today I will share how I use redux to implement a todoList. I hope it will be helpful to you who want to use redux.

(Why is it called the upgraded version? Because I have written a todoList without redux before)

This project uses react’s official create-react-app Architecture, each directory can be divided according to its own needs. The contents and functions of each directory are explained below.

public: mainly contains static resources (entry html files, image resources, JSON files, etc.);

src/component: different components;

src/layouts: the entire The basic structure of the page is mainly Nav, Footer, and Content. User and Notice data are displayed in Nav, and page routing is switched in Content. Footer is fixed;

src/redux:

--src/redux/configureStore: Generates the entire application store;

--src/redux/reducers: a collection of all reducers;

src/routes: the overall routing of the page;

src/utils: self-encapsulated tools ;

views: stores all the pages to be displayed in the project;

index: the entry file of the entire project;

2. Specific implementation

1. What data should be stored in the store in the entire application?

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. Distribution of reducers:

Each state corresponds to a reducer, so a total of four reducers are needed. Merge all reducers in src/redux/reducers, and pay attention to each The name of the reducer should have the same name as the 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,
});

Each state corresponds to a reducer, so like state, the reducer should be placed in the directory of the top-level parent component, so place the reducer of taskListData in In src/views/TodoList, the same applies to other things, the code is as follows:

/*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. Distribution of action creator:

Each action represents an action, and the action is issued by the component, so the action The creator is a separate file and placed in the component directory. For example: action creator of the ListItem component:

/*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,
    });
  }
}


3. How to connect redux to the component

react-redux provides the connect method to combine state and action The creator is bound to the component and then obtained as props inside the component. The following is the specific implementation of the TodoList page:

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);

The connect method has four parameters. Here we mainly talk about the first two parameters:

(1) mapStateToProps: The parameter is state, which is required to return the page All states;

(2) mapDispatchToProps: The parameter is dispatch, and the asynchronous callback function to be used to return the page.

You must have seen it if you have a sharp eye. We exported the bindActionCreators method from the redux package. This method binds dispatch and action creator to trigger actions.

4. How to trigger asynchronous action creator?

Because each action creator is an asynchronous function, what we pass to the component is just the declaration of the function, so we need to introduce our middleware, just add it when generating the store:

/*redux/configureStore.js*/
import { createStore, applyMiddleware } from &#39;redux&#39;;
import thunk from &#39;redux-thunk&#39;;
import reducers from &#39;./reducers&#39;;
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;

In the above code, thunk is a middleware. We just pass the introduced middleware into applyMiddleware.

5. Where does the store pass in the component?

We will definitely think that the store exists in the entire application, so it should be at the top level of the entire application. For general projects, of course it is the top routing:

import React, { Component } from &#39;react&#39;;
import { BrowserRouter as Router, Route } from &#39;react-router-dom&#39;;
import { Provider } from &#39;react-redux&#39;;
import BasicLayout from &#39;../layouts&#39;;
import store from &#39;../redux/configureStore&#39;;
class RouterApp extends Component {
  render () {
    return (
      <Provider store={store}>
        <Router>
          <Route path="/" component={BasicLayout} />
        </Router>
      </Provider>
    );
  }
}
export default RouterApp;

Provider is a component of react-redux, and its function is to pass the store into the entire application.

The above is what I compiled for everyone. I hope it will be helpful to everyone in the future.

Related articles:

How to control multiple scroll bars to scroll synchronously using JS

How to build vue using vue-cli webpack

How to use JS to write Ajax request functions

Chrome Firefox comes with debugging tools (detailed tutorial)

About how Vue.js implements infinite scrolling loading

The above is the detailed content of How to implement todoList through react+redux upgraded version. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn