乐趣区

关于前端:React生态篇如何使用reactredux

一,介绍

React-Redux 是沟通 React 和 Redux 的桥梁,它次要性能体现在如下两个方面:

  1. 在根组件中承受 Redux 的 Store,并把它正当调配到所须要的组件中。
  2. 组件实例订阅 Store 中 state 的扭转,促使生产对应的 state 的组件更新。

装置:
npm install –save react-redux

二,应用

React-Redux 中提供了一个重要的 Provider 组件和一个高阶组件 connect。
1,Provider
redux 提供给 react 数据层,然而数据可能会被很多组件应用,provider 就能够把 redux 中提供的 store 在全局中注入。其作用就是保留 redux 中的 store,调配给所有有须要 store 中数据的子组件。
用法:

export default function Root() {
  return (<Provider store={Store}>
      <Index />
    </Provider>
  );
}

2,connect
connect 能够了解为 Provider 的消费者。能够利用 connect 提供的性能,做数据获取,数据通信,状态派发等操作。
connect 高价组件调用后,组件将领有以下性能:
1, 可能从 props 中获取扭转 Store 中 state 的办法:Store.dispatch
2, 如果 connect 有第一个参数,那么会将 redux Store state 中的数据,映射到以后组件的 props 中,子组件能够应用生产。
3, 当须要的 Store 中的 state,有变动的时候,会告诉以后组件更新,从新渲染视图。
用法:

function connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?)

参数 mapStateToProps:对须要应用 Store 中 state 的业务组件,将 Store 中的数据映射到该业务组件中,Store 中的 state 扭转触发业务组件中的 props 扭转,对应业务组件的视图会更新。当没有该参数时,以后业务组件不会被订阅
用法:

const mapStateToProps = (state) => ({number: state.number});

参数 mapDispatchToProps: 将 redux 中的 dispatch 办法,映射到业务组件的 props 中。

const mapDispatchToProps = (dispatch) => {
  return {numberAdd: () => dispatch({type: "ADD"}),
    setInfo: () => dispatch({ type: "SET"})
  };
};

dispatch 别离会调用 reducer 中对应 type 的操作。

参数 mergeProps:

  • stateProps , state 映射到 props 中的内容
  • dispatchProps,dispatch 映射到 props 中的内容。
  • ownProps 组件自身的 props

用法:

(stateProps, dispatchProps, ownProps) => Object

失常状况下,如果没有这个参数,会依照如下形式进行合并,返回的对象能够是,能够自定义的
合并规定,还能够附加一些属性。
{…ownProps, …stateProps, …dispatchProps}
参数 options: 类型为对象传入

context?: Object, // 自定义上下文
 pure?: boolean, // 默认为 true , 当为 true 的时候,除了 mapStateToProps 和 props , 其余输出或者 state 扭转,均不会更新组件。areStatesEqual?: Function, // 当 pure true , 比拟引进 store 中 state 值 是否和之前相等。(next: Object, prev: Object) => boolean
 areOwnPropsEqual?: Function, // 当 pure true , 比拟 props 值, 是否和之前相等。(next: Object, prev: Object) => boolean
 areStatePropsEqual?: Function, // 当 pure true , 比拟 mapStateToProps 后的值 是否和之前相等。(next: Object, prev: Object) => boolean
 areMergedPropsEqual?: Function, // 当 pure 为 true 时,比拟 通过 mergeProps 合并后的值,是否与之前等 (next: Object, prev: Object) => boolean
 forwardRef?: boolean, // 当为 true 时候, 能够通过 ref 获取被 connect 包裹的组件实例。

三,示例

1, 新建 store 文件
在我的项目目录 src 下新建 Redux 的 Store 目录 (store 文件夹) 并新建 index.js 和 reducer.js 文件
在 index.js 中咱们创立 Store 数据贮存仓库

import {createStore, applyMiddleware, compose} from "redux"; // 引入 createStore 办法
import reducer from "./reducer";

const store = createStore(reducer); // 创立数据存储仓库

export default store;

创立完 Store,咱们能够先在我的项目 index.js 中先引入,应用 Provide 派发

import {StrictMode} from "react";
import ReactDOM from "react-dom";

// import App from "./React-redux-demo/demo02";
import CompA from "./React-redux-demo/compA";
import CompB from "./React-redux-demo/compB";
import {Provider} from "react-redux";
import store from "./store";
const App = (<Provider store={store}>
    {/* <Index /> */}
    <CompA />
    <CompB />
  </Provider>
);
{
  /* <StrictMode>
<App />
</StrictMode>, */
}
const rootElement = document.getElementById("root");
ReactDOM.render(App, rootElement);

创立 compA 和 compB 子组件,并在根组件中引入,如上

import React, {useState, useEffect} from "react";
import {connect} from "react-redux";

function ComponentA({toCompB, compBsay}) {const [CompAsay, setCompAsay] = useState("");
  return (
    <div className="box">
      <p> 我是组件 A </p>
      <div> B 组件对我说:{compBsay} </div>
      我对 B 组件说:<input
        placeholder="CompAsay"
        onChange={(e) => setCompAsay(e.target.value)}
      />
      <button onClick={() => toCompB(CompAsay)}> 确定 </button>
    </div>
  );
}
/* 映射 state 中 CompBsay  */
const CompAMapStateToProps = (state) => ({compBsay: state.info.compBsay});
/* 映射 toCompB 办法到 props 中 */
const CompAmapDispatchToProps = (dispatch) => ({toCompB: (mes) => {dispatch({ type: "SET", payload: { compAsay: mes} });
  }
});
/* connect 包装组件 A */
export default connect(
  CompAMapStateToProps,
  CompAmapDispatchToProps
)(ComponentA);

import {Component} from "react";

import {connect} from "react-redux";
class ComponentB extends Component {state = { compBsay: ""};
  handleToA = () => {
    this.props.dispatch({
      type: "SET",
      payload: {compBsay: this.state.compBsay}
    });
  };
  render() {
    return (
      <div className="box">
        <p> 我是组件 B </p>
        <div> A 组件对我说:{this.props.compAsay} </div>
        我对 A 组件说:<input
          placeholder="CompBsay"
          onChange={(e) => this.setState({compBsay: e.target.value})}
        />
        <button onClick={this.handleToA}> 确定 </button>
      </div>
    );
  }
}
/* 映射 state 中 CompAsay  */
const CompBMapStateToProps = (state) => ({compAsay: state.info.compAsay});
export default connect(CompBMapStateToProps)(ComponentB);

在 reducer.js 中咱们创立 Store 须要贮存的 State 数据

// 定义初始 state
const defaultState = {
  number: 2,
  info: {
    compAsay: "",
    compBsay: ""
  }
};

// 深拷贝
function deepClone(obj) {var objClone = Array.isArray(obj) ? [] : {};
  // 进行深拷贝的不能为空,并且是对象或者是
  if (obj && typeof obj === "object") {for (let key in obj) {if (obj.hasOwnProperty(key)) {if (obj[key] && typeof obj[key] === "object") {objClone[key] = deepClone(obj[key]);
        } else {objClone[key] = obj[key];
        }
      }
    }
  }
  return objClone;
}

export default (state = defaultState, action) => {
  // #reducer 里只能承受 state 不能扭转 state
  if (action.type == "SET" && action.payload.compAsay) {let newState = deepClone(state);  // 深拷贝 state
    newState.info.compAsay = action.payload.compAsay;
    return newState;
  }
  if (action.type == "SET" && action.payload.compBsay) {let newState = deepClone(state);
    newState.info.compBsay = action.payload.compBsay;
    return newState;
  }
  return state;
};
退出移动版