使用Redux的TodoList

React + Redux 写的TodoList

Redux入门

  • Redux 概念简述

React : A JavaScript library for building user interfaces
Redux: Redux = Reducer + Flux
使用Redux的TodoList_第1张图片

  • Redux 的工作流程
    组件 > 表达式 > Store > Reducers查询Store > Store > 组件
    使用Redux的TodoList_第2张图片
  • Antdesign
  • Redux的 Stroe创建 & Action编写
  • npm add redux
  • redux-devtools Chrome插件
    redux-devtools-extension:gitHub
  • createStore要加reducerwindow.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()

Redux知识点补充

  • 三个基本原则:

    • Store 是唯一的,只能有一个
    • 只有 Store 能改变自己的内容
    • Reducer 必须是*纯函数(给固定的输入,一定有固定的输出,不会有副作用)
  • Store >派发 >获取store数据 >订阅数据改变使用Redux的TodoList_第3张图片


  • TodoList.js
import React, { Component } from "react";
import "antd/dist/antd.css";
import { Input, Button, List, message ,Row, Col} from "antd";
import axios from "axios";
import store from './store/index';
import { getInputChangeAction, getAddTodoItem, getDelData }  from './store/actionCreators'
import {CHANGE_INPUT_INPUTVALUE,ADD_TODO_ITEM,DEL_DATA} from './store/actionType'

class TodoList extends Component {
 
    constructor(props) {
    super(props); 
    
    //Store部分
    this.state = store.getState();
    //输出store的数据
    this.handleStoreChange = this.handleStoreChange.bind(this);
    console.log(this.state);
    store.subscribe(this.handleStoreChange);

    this.handleAdd = this.handleAdd.bind(this);
    this.handleChange = this.handleChange.bind(this);
    this.handleDel = this.handleDel.bind(this);
    this.handleClean = this.handleClean.bind(this);
    this.handleAjax = this.handleAjax.bind(this);
  }

  render() {
    return (
      <div style={{ margin: "10px"}}>
          <Input
            value={this.state.inputValue}
            placeholder="add todo"
            onChange={this.handleChange}
            style={{ width:"60%"}}

          />
          <Button
            type="primary"
            onClick={this.handleAdd}
          >
            Add
          </Button>
          <Button
            type="primary"
            onClick={this.handleAjax}
          >
            Export
          </Button>
          <Button
            type="primary"
            onClick={this.handleClean}
          >
            Clean
          </Button>
          <List
            header={<div style={{ textAlign: "center" }}>** TodoList **</div>}
            footer={
              <div style={{ textAlign: "center", fontSize: "10px" }}>
                {" "}
                Copyright Rain{" "}
              </div>
            }
            bordered
            dataSource={this.state.dataObj}
            renderItem={item => (
              <List.Item onClick={this.handleDel}>
                <ul>
                  <li>{item}</li>
                </ul>
              </List.Item>
            )}
            style={{ width: "20rem", margin: "0.5rem" }}
          />
      </div>
    );
  }


  handleAdd() {
    {
    //redux
   const action = getAddTodoItem();
    store.dispatch(action);

  handleStoreChange() {
    this.setState(store.getState());
  }
    //redux
    const action = getInputChangeAction(e.target.value);
    store.dispatch(action);
  }

  handleDel(index) {
    //redux
    const action = getDelData(index);
    store.dispatch(action);
  }

  handleClean() {
    this.setState(
      () => {
        return {
          dataObj: []
        };
      },
      () => {
        message.success("Cleaning successed!", 0.4);
      }
    );
  }

  handleAjax() {
    axios
      .get("/todoList.json")
      .then(res => {
        console.log(res.data);

        this.setState(
          () => {
            return {
              dataObj: [...this.state.dataObj.concat(res.data)]
            };
          },
          () => {
            message.success("Exportint successed!", 0.4);
          }
        );
      })
      .catch(() => {
        message.error("Fail to export!", 1);
      });
  }
}

export default TodoList;


  • store/index.js
import { createStore } from 'redux';
import reducer from './reducer'

const store = createStore(
    reducer,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
    );

export default store;

  • reducer.js
import {CHANGE_INPUT_INPUTVALUE,ADD_TODO_ITEM,DEL_DATA} from './actionType'

const defaultState = {
    inputValue: '默认输入内容',
    dataObj: ["默认内容"]
}

//reducer 可以接受state,但是绝对不能修改state
export default (state = defaultState, action) => {
    if (action.type === CHANGE_INPUT_INPUTVALUE) {   
        const newState = JSON.parse(JSON.stringify(state));
        newState.inputValue = action.value;
        return newState;
    }
    if (action.type === ADD_TODO_ITEM) {
        const newState = JSON.parse(JSON.stringify(state));
        newState.dataObj.push(newState.inputValue);
        newState.inputValue = '';
        return newState;
    }
    if (action.type === DEL_DATA) {
        const newState = JSON.parse(JSON.stringify(state));
        newState.dataObj.splice(action.index,1);
        return newState;
    }
    console.log(state,action);
    return state;
}

  • actionType.js
export const CHANGE_INPUT_INPUTVALUE = 'change_input_inputValue';
export const ADD_TODO_ITEM = ADD_TODO_ITEM;
export const DEL_DATA = DEL_DATA;

  • actionCreators.js
import { CHANGE_INPUT_INPUTVALUE, ADD_TODO_ITEM, DEL_DATA } from "./actionType";

export const getInputChangeAction = (value) => ({
    type:  CHANGE_INPUT_INPUTVALUE,
    value
})

export const getAddTodoItem = () => ({
    type:  ADD_TODO_ITEM,
})

export const getDelData = (index) => ({
    type:  DEL_DATA,
    index
})

  • index.js
import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList'

ReactDOM.render(<TodoList />, document.getElementById('root'));

你可能感兴趣的:(React.js)