Redux的使用与总结

在介绍redux之前,大家应该了解redux的作用,为什么会有redux的出现?

我们知道react是现在特别火的一个前端框架,很多知名企业都在使用react,所以我们应该要知道react的定位。react的其实是一个ui框架,很多事情react并不是自己来完成,而是交给其他组件来完成。比如react基于state的数据管理交给redux来做,ajax请求的发送交给axios来做等等。react父子组件之间的数据传递其实是很简单的,如果子组件想修改父组件中的state,我们就得先在父组件中定义函数,该函数的作用就是setState修改父组件的state中的数据,那子组件就可以利用props接受父组件传递过来的函数,来间接的调用父组件中修改satate的方法,来达到目的。但是当一个页面非常的复杂,所有的组件不是简单的父子关系,甚至会出现十几层的组件调用,那这种场景下,如果我们还是用原来的方式一层一层的进行数据传递,就会出现‘曼妥思与可乐效应’。 所以这篇文章其实是告诉大家redux是如何来帮助react进行数据管理的,但是有句话要说前面,不是学会了redux之后,所有的项目都用redux来进行数据管理,我们不仅需要知道redux的有点,还需要知道redux的缺点,知道哪些场景是不适合使用redux的。

redux的三大核心

action

action这个概念其实不难理解,我们在需要修改state的数据的时候,会首先发出一个action,一般的action长这样:

{
  type: 'ADD_TODO',
  text: 'Build my first Redux app'
}

每一个action都有type都有一个type,标记着这个任务的类型,它的作用就是在后面进行修改state数据的时候告诉reduer:什么样action我应该进行对应的操作。大家其实也看得出来,这个type是有手工定义的一个字符串,那既然是常量字符串我们就应该将他管理起来,创建函数返回单一的action,创建常量来管理type,从而进行父组件的代码优化。

function addTodo(text) {
  return {
    type: 'ADD_TODO',
    text
  }
}

//contants.js
export const VisibilityFilters = {
  SHOW_ALL: 'SHOW_ALL',
  SHOW_COMPLETED: 'SHOW_COMPLETED',
  SHOW_ACTIVE: 'SHOW_ACTIVE'
}

text就是传递的数据参数,reducer在进行修改state值得时候可能会利用到这里的参数,所以这里的text就起到这样一个作用。其实我们可以把action理解为信鸽,每一个action都是消息的传递者,传递的数据流就是绑在信鸽腿上的信。

store:

我们说action是消息的传递者,那么action到底传递给谁呢?那我又是如何监听state被reducer修改了呢?

store其实是redux进行数据管理的核心。它提供createStore 的getState()方法来获取state,通过dispatch(action)来派发action,通过suscribe来监听state数据是否发生改变,需要抢到一下 Redux 应用只有一个单一的 store。当需要拆分数据处理逻辑时,你应该使用 reducer 组合而不是创建多个 store。

首先我们来看一下store如何创建:

1、首先我们在src目录下创建一个store文件夹,接着再建一个index.js文件

下面是store下面的index.js的内容:

import {createStore} from 'redux';
import reducer from './reducer';

const store = createStore(reducer);

export default store;

最后回到父组件再去使用这个store,下面的代码是个例子:

//todolist.js
import React, { Component } from 'react'
import 'antd/dist/antd.css';
import store from './store/index.js';
import {getInitList, getInputChangeAction, getAddTodoItem, getDeleteTodoItem} from './store/actionCreators';
import ToListUI from './TodoListUI';


class TodoList extends Component{

  constructor(props){
    super(props);
    this.state = store.getState()
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleStoreChanged = this.handleStoreChanged.bind(this);
    this.handleBtnClick = this.handleBtnClick.bind(this);
    this.handleItemDelete = this.handleItemDelete.bind(this);
    //监听store是否发生改变,一旦发生改变store就会执行subscribe函数
    store.subscribe(this.handleStoreChanged);
  }

  render() {
    return <ToListUI 
      inputValue={this.state.inputValue}
      list={this.state.list}
      handleInputChange={this.handleInputChange}
      handleBtnClick={this.handleBtnClick}
      handleItemDelete={this.handleItemDelete}
    />
  }

  componentDidMount(){
    const action = getInitList();
    store.dispatch(action);
    // axios.get('/list.json')
    // .then((res) => {
    //   const data = res.data;
    //   const action = initListAction(data);
    //   store.dispatch(action);
    // })
    //redux-thunk
    // const action = getTodoList();
    // //store如果发现这个action是个函数那么就会自动执行这个action函数
    // //这就是actionCreators中getTodoList()方法会执行的原因
    // store.dispatch(action);
  }

  handleStoreChanged() {
    this.setState(store.getState());
  }

  handleInputChange(e){
    const action = getInputChangeAction(e.target.value)
    store.dispatch(action);
  }

  handleBtnClick(){
    const action = getAddTodoItem();
    store.dispatch(action);
  }
  
  handleItemDelete(index){
    const action = getDeleteTodoItem(index);
    store.dispatch(action);
  }

}

export default TodoList;

我们首先将store给import进来,然后getState()获取到store下面的state赋值给当前组件下的state,每一个动作都派发一个action给reducer,下面reducre登场。

reducer:

reducer其实可以理解为store的秘书,store会把action告诉reducer,reducer也可以接收到store中state更新之前的state,最后根据action中定义的type做不同的事情,将修改后的state以一个新的state返回。

import {CHANGE_INPUT_VALUE,ADD_TODO_ITEM,DELETE_TODO_ITEM,INIT_LIST_ACTION} from './actionTypes';

const defaultState = {
    inputValue: '闻声识雨',
    list: []
}

//reducer可以接受state但是绝不能修改state,所以需要拷贝到newState
//纯函数指的是,给固定的输入,就一定会有固定的输出,而且不会有副作用
export default (state = defaultState, action) => {
    if(action.type === CHANGE_INPUT_VALUE){
      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.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;
    }
    if(action.type === INIT_LIST_ACTION){
      const newState = JSON.parse(JSON.stringify(state));
      newState.list = action.data;
      return newState;
    }
    return state;
}

以上呢就是redux的三大核心的简单的介绍,但是需要搞懂,真是需要自己亲自实践一番,了解redux中这三个概念的数据流转,相互关系。

官网直通车:redux官网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值