react-redux

redux的创建

redux的使用需要创建四个文件,分别为action,reducer,store和constant

  1. action:专门用于为组件生成action对象的文件,每一个需要用到redux的组件都需要创建一个对应的action文件
    (创建action对象,即创建组件想要加工数据的方式)
/*
  该文件专门用于为Count组件生成action对象
*/
import { INCREMENT, DECREMENT } from '../constant';

// 同步action,就是指action的值为Object类型的一般对象
export const createIncrementAction = data => { return { type: INCREMENT, data } }
export const createDecrementAction = data => { return { type: DECREMENT, data } }

// 异步action,就是指action的值为函数,异步action中一般都会调用同步action,异步action不是必须要用的
export const createIncrementAsyncAction = (data, time) => {
  return (dispatch) => {
    setTimeout(() => {
      dispatch(createIncrementAction(data))
    },time)
  }
}
  1. reducer:用于手动创建一个为组件服务的reducer,其本质是一个函数
    (根据组件传入action参数类型判断如何加工数据)
/*
  1.该文件用于手动创建一个为Count组件服务的reducer,其本质是一个函数
  2.reducer函数会接到两个参数,分别为之前的状态(preState),动作对象(action)
*/
import {INCREMENT,DECREMENT} from '../constant';

// 初始化preState的值,如果为undefined则为0
const initState = 0
export default function countReducer(preState = initState, action) {
  // 从action对象中获取: type、data
  const { type, data } = action
  // 根据type决定如何加工数据
  switch (type) {
    case INCREMENT:
      return preState + data
    case DECREMENT:
      return preState - data
    default:
      return preState
  }
}
  1. store:专门用于暴露一个store对象,整个引用只有一个store对象
    (redux核心文件)
/*
  该文件专门用于暴露一个store对象,整个引用只有一个store对象
*/

// 引入createStore,专门用于创建redux中最为核心的store对象
// applyMiddleware用于引用thunk中间件
// combineReducers用于汇总所有的reducers变为一个reducer
import { createStore, applyMiddleware, combineReducers } from 'redux'
// 引入为Count组件服务的reducer
import countReducer from './reducers/count';
// 引入为Person组件服务的reducer
import personReducer from './reducers/person';
// 引入redux-thunk,用于支持异步action
import thunk from 'redux-thunk';

const reducer = combineReducers({
  countReducer,
  personReducer
})

const store = createStore(reducer, applyMiddleware(thunk))

export default store
  1. constant:用于定义action对象中的type类型的常量值,便于管理的同时防止写错
    (便于后期维护)
/*
  该模块用于定义action对象中的type类型的常量值,便于管理的同时防止写错
*/

// 定义加法
export const INCREMENT = 'increment'
// 定义减法
export const DECREMENT = 'decrement'
// 定义添加一个人的信息
export const Add_Person = 'add_person'

App组件的使用

组件的挂载应该引入容器组件,而不是UI组件

import React, { Component } from 'react';
import Count from './containers/Count';
import Person from './containers/Person';

export default class App extends Component {
  render() {
    return (
      <div>
        <Count />
        <hr />
        <Person/>
      </div>
    );
  }
}

入口文件index.js的使用

入口文件中需要注意的是

  1. store的状态更新不会自动重新渲染页面,需要subscribe()监测store状态更新,而react-redux中的connect可以自动监测store状态更新,所以可以略去
  2. 在容器组件与redux、UI组件相关联时,redux通过props传递store状态给容器组件,由于每个容器组件都要传过于繁琐,使用Provider可以给App里的所有容器组件匹配store
import React from 'react';
import ReactDom from 'react-dom';
import store from './redux/store';
import { Provider } from 'react-redux'
import App from './App';

ReactDom.render(
  // react-redux的Provide可以给App里的所有组件匹配store
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

// 监测store状态更新
// react-redux的connect可以自动检测store状态更新
// store.subscribe(() => {
//   ReactDom.render(<App />, document.getElementById('root'))
// })

容器组件

  1. 由于UI组件不能直接从redux中的store中获取状态state以及获取更新状态的方法,所以容器组件就充当了一个中间桥梁的作用
  2. 引入connect,connect()()中的第二个括号连接UI组件,第一个括号用以映射store中的状态和操作状态的方法
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {
  createIncrementAction,
  createDecrementAction,
  createIncrementAsyncAction
} from '../../redux/actions/count';

class Count extends Component {

  increment = () => {
    this.props.increment(this.selectNumber.value*1)
  }

  decrement = () => {
    this.props.decrement(this.selectNumber.value*1)
  }

  incrementIfOdd = () => {
    if (this.props.count % 2 !== 0) {  
      this.props.increment(this.selectNumber.value*1)
    }
  }

  incrementAsync = () => {
    this.props.incrementAsync(this.selectNumber.value*1, 500)
  }

  render() {
    return (
      <div>
        <h2>当前求和为:{ this.props.count }</h2>
        <select ref={c => this.selectNumber = c}>
          <option value='1'>1</option>
          <option value='2'>2</option>
          <option value='3'>3</option>
        </select>
        <button onClick={this.increment}>+</button>&nbsp;
        <button onClick={this.decrement}>-</button>&nbsp;
        <button onClick={this.incrementIfOdd}>当前求和为奇数再加</button>&nbsp;
        <button onClick={this.incrementAsync}>异步加</button>
      </div>
    );
  }
}

export default connect(
  state => ({ count: state.countReducer }), // 映射状态
  {
    increment: createIncrementAction,
    decrement: createDecrementAction,
    incrementAsync: createIncrementAsyncAction
  } // 映射操作状态的方法
)(Count)

在引入react-redux之前使用store

  1. 需要引入store文件
  2. 使用dispatch(action)修改状态
  3. 使用getState()获取store状态
import React, { Component } from 'react'
import store from '../../redux/store';
import { createIncrementAction, createDecrementAction, createIncrementAsyncAction} from '../../redux/count_action';


export default class Count extends Component {

    //加法
  increment = () => {
    const {value} = this.selectNumber
    // 通知redux加value
        store.dispatch(createIncrementAction(value * 1))
    }
    //减法
  decrement = () => {
    const {value} = this.selectNumber
    // 通知redux减value
    store.dispatch(createDecrementAction(value * 1))
    }
    //奇数再加
  incrementIfOdd = () => {
    const { value } = this.selectNumber
        let count  = store.getState()
    // 通知redux加value
    if(count % 2 !== 0){
      store.dispatch(createIncrementAction(value * 1))
    }
    }
    //异步加
  incrementAsync = () => {
        const { value } = this.selectNumber
        store.dispatch(createIncrementAsyncAction(value * 1, 500))
    }

    render() {
        return (
            <div>
                <h1>当前求和为:{ store.getState() }</h1>
                <select ref={c => this.selectNumber = c}>
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                </select>&nbsp;
                <button onClick={this.increment}>+</button>&nbsp;
                <button onClick={this.decrement}>-</button>&nbsp;
                <button onClick={this.incrementIfOdd}>当前求和为奇数再加</button>&nbsp;
                <button onClick={this.incrementAsync}>异步加</button>&nbsp;
            </div>
        )
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容