Redux总结

109 阅读2分钟

Redux 重要API

Reducer 函数 就是根据旧的state返回新的state

const reducer = (state, action)=>{
  if(state === undefined){
    return {n: 0}
  }else{
    if(action.type === 'add'){
      var newState = {n: state.n + action.payload}
      return newState
    }else{
      return state
    }
  }
}

store

const store = createStore(reducer)

store.subscribe

store.subscribe(()=>{
  render()
})

store.dispatch

store.dispatch({type:'add', payload: 1})

React-Redux

Provider 标签

  <Provider store={store}>
    <App />
  </Provider>, 

connect 函数

function mapStateToProps(state){
  return {
    n: state.n
  }
}
function mapDispatchToProps(dispatch) {
  return {
    add1: ()=> dispatch({type:'add', payload: 1})
  }
}

export default connect(mapStateToProps,mapDispatchToProps)(App);

简单例子

实现如图的简单功能

原生JS + Redux

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>hi redux</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="https://cdn.bootcdn.net/ajax/libs/redux/4.0.5/redux.min.js"></script>
    <script>
      function add1() {
        store.dispatch({ type"add"payload1 });
        // dispatch 一个 action
        // 触发一个事件
        // 派发一个动作
      }
      function add2() {
        store.dispatch({ type"add"payload2 });
      }
      function addIf() {
        let oldState = store.getState();
        if (oldState % 2 === 1) {
          store.dispatch({ type"add"payload1 });
        }
      }
      function addAsync() {
        setTimeout(() => {
          store.dispatch({ type"add"payload1 });
        }, 2000);
      }
      function render(store) {
        const app = document.querySelector("#app");
        app.innerHTML = `
            <div>
                你点击了 <span id="value">${store.getState()}</span>次
                <div>
                    <button id="add1" onclick="add1()">+1</button>
                    <button id="add2" onclick="add2()">+2</button>
                    <button id="add1IfOdd" onclick="addIf()">如果是单数就+1</button>
                    <button id="add1After2Sec" onclick="addAsync()">两秒钟后+1</button>
                </div>
            </div>
            `;
      }
      function stateChanger(state, action) {
        if (state === undefined) {
          return 0;
        } else {
          if (action.type === "add") {
            let newState = state + action.payload;
            return newState; //根据操作生成新的state 触发一个事件
          } else {
            return state;
          }
        }
      }
      let store = Redux.createStore(stateChanger);
      render(store);
      store.subscribe(() => {
        render(store); // 接收到事件,重新render
      });
    </script>
  </body>
</html>

store 存储了 state 想要获取state通过store.getState()

Redux + React

index.js

import React from "react";
import ReactDOM, { render } from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { createStore } from "redux";
const reducer = (state, action) => {
  if (state === undefined) {
    return 0;
  } else {
    if (action.type === "add") {
      let newState = (state += action.payload);
      return newState;
    } else {
      return state;
    }
  }
};
const store = createStore(reducer);
renders();
store.subscribe(() => {
  renders();
});
function add3(){
  if(store.getState() % 2 === 1){
    store.dispatch({type:'add',payload:1})
  }
}
function add4(){
  setTimeout(()=>{
    store.dispatch({type:'add',payload:1})
  },2000)
}
function renders() {
  ReactDOM.render(
    <React.StrictMode>
      <App
        value={store.getState()}
        onAdd1={() => {
          store.dispatch({ type: "add", payload: 1 });
        }}
        onAdd2={() => {
          store.dispatch({ type: "add", payload: 2 });
        }}
        onAdd3={add3}
        onAdd4={add4}
      />
    </React.StrictMode>,
    document.getElementById("root")
  );
}

reportWebVitals();

App.js

import React, { Component } from "react";
class App extends Component {
  add1 = () => {
    this.props.onAdd1()
  }
  add2 = () => {
    this.props.onAdd2()
  }
  add3 = () => {
    this.props.onAdd3()
  }
  add4 = () => {
    this.props.onAdd4()
  }
  render() {
    return (
      <div>
        你点击了 <span id="value">{this.props.value}</span>次
        <div>
          <button id="add1" onClick={this.add1}>+1</button>
          <button id="add2" onClick={this.add2}>+2</button>
          <button id="add1IfOdd" onClick={this.add3}>如果是单数就+1</button>
          <button id="add1After2Sec" onClick={this.add4}>两秒钟后+1</button>
        </div>
      </div>
    );
  }
}
export default App;

Redux + React + React-Redux

  • React-Redux可以让你随时访问stroe,而且不会混乱
  • Provider会把store传给里面的每一个组件,并且会自动渲染
  • connect是一个高阶函数,接收一个mapStateToProps参数也就是把全局的state映射到当前组件的props,必须是一个函数,第二个参数mapDispatchToProps,把dispatch映射到props,两种形式可以是个函数,也可以是个对象,还接收一个组件作为参数返回一个具有状态的组件
  • connect会把这两个参数合并起来,作为props传给App

index.js

import React from "react";,
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { createStore } from "redux";
import { Provider } from "react-redux";
const reducer = (state, action) => {
  if (state === undefined) {
    return {n:0};
  } else {
    if (action.type === "add") {
      let newState = {n: state.n + action.payload};
      return newState;
    } else {
      return state;
    }
  }
};
const store = createStore(reducer);
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);
reportWebVitals();

App.js

import React, { Component } from "react";
import { connect } from "react-redux";
class App extends Component {
  render() {
    return (
      <div>
        你点击了 <span id="value">{this.props.n}</span>次
        <div>
          <button id="add1" onClick={() => this.props.add1()}>
            +1
          </button>
          <button id="add2">+2</button>
          <button id="add1IfOdd">如果是单数就+1</button>
          <button id="add1After2Sec">两秒钟后+1</button>
        </div>
      </div>
    );
  }
}
function mapStateToProps(state) {
  return {
    n: state.n,
  };
}
function mapDispatchToProps(dispatch) {
  return {
    add1() => dispatch({ type"add"payload1 }),
  };
}
export default connect(mapStateToProps, mapDispatchToProps )(App);