React 之 Redux 的使用

Posted cckui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React 之 Redux 的使用相关的知识,希望对你有一定的参考价值。

1. Redux使用场景

  1. 某个组件的状态,需要共享
  2. 不同组件之间通信

2. Redux 特点

技术图片

2.1 Store

store是一个数据仓库,一个应用中store是唯一的,它里面封装了state状态,当用户想访问state的时候,只能通过store.getState()来取得state对象。

2.2 action

action描述了一个更新state的动作,它是一个对象,其中type属性是必须有的,它指定了某动作和要修改的值:


    type: CHANGE_INPUT_VALUE,
    value: 'abc'

2.3 actionCreator

actionCreator 是一个方法,用来创建action对象,调用这个方法就能返回一个action对象,用于简化代码

2.4 dispatch

dispatch 是一个方法,它用于派发一个动作action,这是唯一的一个能够修改state的方法,它内部会调用reducer来调用不同的逻辑基于旧的state来更新出一个新的state。

2.5 reducer

reducer是更新state的核心,它里面封装了更新state的逻辑,reducer由外界提供(封装业务逻辑,在createStore时传入),并传入旧state对象和action,将新值更新到旧的state对象上返回。

3. Redux 三大原则

3.1 单一数据源

整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。组件通过如下方式取出state中数据:

console.log(store.getState())

3.2 State 是只读的

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

store.dispatch(
  type: 'CHANGE_INPUT_VALUE',
  value: 'abc'
)

3.3 使用纯函数来执行修改 reducers

为了描述 action 如何改变 state tree ,你需要编写 reducers。Reducer 只是一些纯函数,它接收先前的 state 和 action,并返回新的 state。

const defaultState =  // 默认一个state
    inputValue: 'abc',
    list: [1,2,3]
;
 
export default (state = defaultState, action) => 
    console.log(state, action);
    if (action.type === 'CHANGE_INPUT_VALUE') 
        let newState = JSON.parse(JSON.stringify(state)); // 深拷贝一份state
        newState.inputValue = action.value;  // 更改拷贝后的state
        return newState;  // 将更新后的新的state 返回给 store
     
    return state;

4 示例应用 - Todolist

技术图片

入口文件 /src/index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Todolist from './Todolist';

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

新建文件 src/Todolist.js

import React,  Component, Fragment  from 'react'; 

class TodoList extends Component 
 
  render() 
    return (
      <Fragment>
        <div style=padding: '10px'> 
          todolist
        </div>
      </Fragment>
    )
  


export default TodoList;

4.1 创建 store

新建目录: /src/store

4.2 store 入口文件

创建文件:/src/store/index.js:

import  createStore  from 'redux'
import reducer from './reducer'

const store = createStore(reducer)

export default store

4.3 统一定义action.type

新建文件:/src/store/actionType.js,

export const CHANGE_INPUT_VALUE = 'change_input_value';  // 更改input处输入框里面的值
export const ADD_TOTO_ITEM = 'add_todo_item';  // 添加待办事项
export const DELETE_TODO_ITEM = 'detete_todo_item';   // 删除待办事项

4.4 创建action对象

新建文件:/src/store/actionCreator.js

// 引入 actionType 模块
import 
    CHANGE_INPUT_VALUE,
    ADD_TOTO_ITEM,
    DELETE_TODO_ITEM,
 from './actionType'

// 更改input处输入框里面的值
export const getInputChangeAction = (value) => 
    return 
        type: CHANGE_INPUT_VALUE,
        value
    


// 添加待办事项
export const getAddItemAction = () => 
    return 
        type: ADD_TOTO_ITEM
    


// 删除待办事项
export const getDeleteItemAction = (index) => 
    return 
        type: DELETE_TODO_ITEM,
        index
    

4.5 reducer 更新 state

新建文件:/src/store/reducer.js

import 
    CHANGE_INPUT_VALUE,
    ADD_TOTO_ITEM,
    DELETE_TODO_ITEM,
 from './actionType'

const defaultState =  // 默认一个state
    inputValue: 'abc',
    list: [1,2,3]
;

// 注意:reducer 可以接收state, 但是不允许修改state,所以需要深拷贝一份state
export default (state = defaultState, action) => 
    console.log(state, action);
    if (action.type === CHANGE_INPUT_VALUE) 
        let newState = JSON.parse(JSON.stringify(state)); // 深拷贝一份state
        newState.inputValue = action.value;  // 更改拷贝后的state
        return newState;  // 将更新后的新的state 返回给 store
    
    if (action.type === ADD_TOTO_ITEM) 
        let newState = JSON.parse(JSON.stringify(state));
        newState.list.push(newState.inputValue);
        newState.inputValue = '';
        return newState;
    
    if (action.type === DELETE_TODO_ITEM) 
        let newState = JSON.parse(JSON.stringify(state));
        newState.list.splice(action.index, 1); // 删除当前index的item
        return newState;
    
    return state;

4.6 修改 src/Todolist.js

import React,  Component, Fragment  from 'react';
import "antd/dist/antd.css";
import  Input, Button, List  from 'antd';
import store from './store/index';
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.handleBtnClick = this.handleBtnClick.bind(this);

    this.handleStoreChange = this.handleStoreChange.bind(this);
    // 订阅store,只要store中state有变化,就执行handleStoreState函数
    store.subscribe(this.handleStoreChange);
  

  handleInputChange (e)  
    const action = getInputChangeAction(e.target.value);

    // 将需要执行的action传给store
    store.dispatch(action);
  

  handleBtnClick () 
    const action = getAddItemAction();
    store.dispatch(action);
  

  handleItemDelete (index) 
    const action = getDeleteItemAction(index);
    store.dispatch(action);
  

  handleStoreChange () 
    // 当store中state变化时,则重新取一次数据进行替换
    this.setState(store.getState());
  


  render() 
    return (
      <Fragment>
        <div style=padding: '10px'>
          <div>
            <Input
              value=this.state.inputValue
              placeholder="input something"
              style=width: '300px',marginRight: '10px'
              onChange=this.handleInputChange
            />
            <Button type="primary" onClick=this.handleBtnClick>提交</Button>
          </div>
          <List
            style=marginTop: '10px', width: '300px'
            bordered
            dataSource=this.state.list
            renderItem=
              (item, index) => <List.Item onClick=this.handleItemDelete.bind(this, index)>item</List.Item>
            
          />
        </div>
      </Fragment>
    )
  


export default TodoList;

5 项目目录

技术图片

以上是关于React 之 Redux 的使用的主要内容,如果未能解决你的问题,请参考以下文章

React入门之Redux:react-redux基本使用

React 之 Redux 的使用

Redux 进阶之 react-redux 和 redux-thunk 的应用

13react 之 redux

React之redux的基本使用

React-redux框架之connect()与Provider组件 用法讲解