redux、react-redux

138 阅读2分钟

redux

redux-principle.png

redux 完整版

store/index.js
import { createStore, applyMiddleware, combineReducers } from "redux";
import thunk from "redux-thunk";
import home from "./reducers/home";
import about from "./reducers/about";
// 用于配置redux开发者工具
import { composeWithDevTools } from "redux-devtools-extension";
/**
 * createStore 创建redux
 * applyMiddleware、thunk一起使用,实现异步action
 * combineReducers 使用多个reducer时,需要整合reducer
**/
export default createStore(
    // 如果是单个直接写用到的reducer,比如home
    combineReducers({
        home,
        about,
    }),
    // 需要配置redux开发者工具,不需要就applyMiddleware(thunk)
    composeWithDevTools(applyMiddleware(thunk))
);

store/reducers/home.js
/**
 * 纯函数:
 *   函数的返回结果只依赖于它的参数
 *   函数执行过程中没有副作用,比如:网络请求、输入和输出设备
 *   不能改变参数
 *   不能使用不纯的方法,比如:Date.now()、Math.random()等 
 * reducer就是纯函数,纯函数靠谱
**/
export default (preState = [1, 2, 3], action) => {
  let { type, data } = action;
  switch (type) {
    case "add":
      return [...preState, data];
    default:
      return preState;
  }
};

store/actions/home.js
// 同步写法
export const increment = (data) => ({type: "increment", data})

// 异步写法
export const incrementAsync = (data, time) => {
    return (dispatch) => {
        setTimeout(() => {
            dispatch(increment(data)); // dispatch里传入action
        }, time)
    }
}

在组件里使用redux
import store from "../../store";
// 记不得store的属性可以输出看一下

// 获取状态
store.getState()
// 如果reducer使用了combineReducers进行了整合
store.getState().reducer// 修改状态
store.dispatch(action)

redux只负责状态管理,不负责随着状态的改变驱动页面的改变
单个组件里可以使用:
    componentDidMount() {
        store.subscribe(() => {
            this.setState({});
        })
    }

全局的改变
src/index.js
import store from "./store";

// 新增
store.subscribe(() => {
    ReactDOM.render(<App />, document.getElementById("root"));
})

react-redux

react-redux.png

react-redux 完整版

容器组件和UI组件写在一起,方便查看
react-redux会随着状态的改变页面随之改变,只需要通过Provider传store
src/index.js
import { Provider } from "react-redux";
import store from "./store";

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

src/containers/home.js
import React, { Component } from "react";
import { connect } from "react-redux"

class Home extends Component {
  // 通过props查看容器传过来的lxh、action名1、action名2
  render() {
    return <div>Home</div>;
  }
}

/**
 * connect()()
 * 第一个括号传入两个函数,ui组件通过props获取到这个两个函数传过来的状态和修改状态的方法
 *   mapStateToProps 获取状态
 *   mapDispatchToProps 修改状态
 * 第二个括号传入的是ui组件
 **/
export default connect(
  state => ({ lxh: state }),
  // 使用combineReducers的写法: state => ({ lxh: state.reducer名 }),

  // mapDispatchToProps简写,对象名和action名一样才能这样写
  {
    action名1,
    action名2,
  }
  /**
   * mapDispatchToProps一般写法
   * (dispatch) => ({
   *     lxh1: (data) => dispatch({type: "type", data}),
   *     lxh2: (data) => dispatch(increment(data)),
   * })
   **/
)(Home);

react