文章12
标签10
分类3

React Redux笔记

Redux笔记记录

Redux 概念简述:

** Redux将组件所有数据放在Store里,改变一个数据后,所有组件根据store里的数据变化进行修改**

Redux 工作流程:


React Components : 借书的用户
Action Creators: 你说的要借什么书的话
Store: 图书馆管理员
Reducers: 记录本

Redux三大原则

1.单一数据源

整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。

2.State 是只读的

唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。

3.使用纯函数来执行修改

为了描述 action 如何改变 state tree ,你需要编写 reducers。纯函数3条件
1.不得修改传入的参数
2.不得调用非纯函数,如Date.now()
3.不得执行有副作用的操作,如API请求和路由跳转

Redux 安装:

npm install redux --save

Redux 谷歌浏览器插件安装:

安装地址: https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?utm_source=chrome-ntp-icon
使用代码:

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

创建一个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;

创建一个Reducers 接收组件发送回来的action 进行对应的数据操作。reducer.js

reducer可以接受state,但是绝不能修改state,需要深度克隆一份state数据,对克隆完的数据操作完后,返回给store。

组件数据更新

store.subscribe() 监听组件数据变化,变化则写一个方法更新组件的数据。

抽离action.type 到 actionTypes, action所有动作到actionCreator:

将action.type里面的字符串 作为常量用一个文件actionTypes.js进行抽离,以便于防止输错action.type字符串项目不好维护。提高项目可维护性。

TodoListDemo

/store/actionCreators.js

import { CHANGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM } from "./actionTYpes";

export const getInputChangeAction = (value) => ({
     type: CHANGE_INPUT_VALUE,
     value
})
export const getAddItemAction = () => ({
    type: ADD_TODO_ITEM
})
export const getDeleteItemAction= (index) => ({
    type: DELETE_TODO_ITEM,
    index
})

/store/actionTypes.js

export const CHANGE_INPUT_VALUE = 'change_input-value';
export const ADD_TODO_ITEM = 'add_todo_item';
export const DELETE_TODO_ITEM = 'delete_todo_item';

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

/store/reducer.js

import { CHANGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM } from './actionTYpes'
const defaultState = {
    inputValue: '',
    list: []
};
export default (state = defaultState, action) => {
    console.log('aaaaaaa', action)
    if (action.type === CHANGE_INPUT_VALUE) {
        const newState = JSON.parse(JSON.stringify(state));
        newState.inputValue = action.value;
        return newState;
    } else if (action.type === ADD_TODO_ITEM) {
        const newState = JSON.parse(JSON.stringify(state));
        newState.list.push(newState.inputValue);
        newState.inputValue ='';
        return newState;
    }
    if (action.type === DELETE_TODO_ITEM) {
        const newState = JSON.parse(JSON.stringify(state));
        newState.list.splice(action.index, 1);
        return newState;
    }
    return state
}

/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList';
ReactDOM.render(, document.getElementById('root'));

/TodoList.js

import React, { Component } from 'react';
import 'antd/dist/antd.css';
import { Input, Button, List } from 'antd';
import store from './store/';
import { getInputChangeAction, getAddItemAction, getDeleteItemAction } from './store/actionCreators';

class TodoList extends Component {
    constructor(props) {
        super(props);
        this.state = store.getState();
        this.handleInputChange= this.handleInputChange.bind(this);
        this.handleStoreChange=this.handleStoreChange.bind(this);
        this.handleBtnClick = this.handleBtnClick.bind(this);
        store.subscribe(this.handleStoreChange)
    }
    render() {
        return (
            <div>
                <div>
                   <Input placeholder='todo info' 
                    value={this.state.inputValue}
                    style={{ width: '300px', marginRight: '10px' }}
                    onChange={this.handleInputChange} />
                    <Button type='primary' onClick={this.handleBtnClick}>添加</Button>
                </div>
                 <List bordered dataSource={this.state.list} renderItem={(item, index) => (<List.Item onClick={this.handleItemDelete.bind(this, index)}>{item}</List.Item>)}  style={{marginTop: '10px', width: '300px'}} />
            </div>
        )
    }
    handleInputChange(e) {
        const action = getInputChangeAction(e.target.value);
        store.dispatch(action)
    }
    handleStoreChange() {
       this.setState(store.getState())
    }
    handleBtnClick () {
        const action = getAddItemAction();
        store.dispatch(action)
    }
    handleItemDelete (index) {
        const action = getDeleteItemAction(index)
        store.dispatch(action)
    }
}
export default TodoList;
本文作者:Bunrun
本文链接:https://www.bugrun.cn/posts/9c6e.html
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可