1. 为什么应该使用 React-Redux
- React-Redux 是 React 的官方 Redux UI 绑定库。如果想要同时使用 Redux 和 React,你也应该使用
2. React Redux API原理
2.1.connect
connect 是 React-Redux 提供的一个高阶组件,用来连接 React 组件与 Redux store,通常用于类组件。它会自动将 Redux store 中的 state 和 dispatch 方法作为 props 传递给组件。
- connect.jsx
function connect(mapStateProps, mapDispatchProps) {
return function (OldComponent) {
return class extends React.Component {
static contextType = ReactReduxContext;
constructor(props, context) {
super(props);
this.store = context.store;
const { getState, subscribe, dispatch } = context.store;
this.state = mapStateProps(getState());
this.dispatch = context.store.dispatch;
this.unsubscribe = subscribe(() => {
this.setState(mapStateProps(getState()));
});
let dispatchProps;
if (typeof mapDispatchProps === 'function') {
dispatchProps = mapDispatchProps(dispatch);
} else if (!dispatchProps) {
dispatchProps = {
dispatch: dispatch,
};
} else {
dispatchProps = bindActionCreators(
mapDispatchProps,
dispatch
);
}
this.dispatchProps = dispatchProps;
}
componentWillUnmount() {
this.unsubscribe();
}
render() {
console.log(this);
return (
<OldComponent
{...this.props}
{...this.state}
{...this.dispatchProps}
></OldComponent>
);
}
};
};
}
export default connect;
2.2.Provider
import React, { Component } from 'react';
import ReactReduxContext from './Context';
export default class Provider extends Component {
constructor(props) {
super(props);
}
render() {
return (
<ReactReduxContext.Provider value={{ store: this.props.store }}>
{this.props.children}
</ReactReduxContext.Provider>
);
}
}
2.3.Context
import React from 'react'
export const ReactReduxContext = React.createContext(null)
export default ReactReduxContext
2.4.useStore
import ReactReduxContext from '../Context';
import { useContext } from 'react';
function useStore() {
const { store } = useContext(ReactReduxContext);
return store;
}
export default useStore;
2.5.useSelector
import ReactReduxContext from '../Context';
import React from 'react';
export default function useSelector(selector, options) {
const { store } = React.useContext(ReactReduxContext);
const state = store.getState();
const selectedState = selector(state);
const [, forceRender] = React.useReducer((s) => s + 1, 0);
React.useEffect(() => {
const unsubscribe = store.subscribe(() => {
forceRender();
});
return () => {
unsubscribe();
};
}, [store]);
return selectedState;
}
2.6.useDispatch
import ReactReduxContext from '../Context';
import React from 'react';
export default function useDispatch(a) {
const { store } = React.useContext(ReactReduxContext);
return store.dispatch;
}
2.7.useBoundDispatch
import { useContext } from 'react';
import ReactReduxContext from '../Context';
import bindActionCreators from '../../redux/bindActionCreators';
function useBoundDispatch(actions) {
const { store } = useContext(ReactReduxContext);
const boundDispatch = bindActionCreators(actions, store.dispatch);
return boundDispatch;
}
export default useBoundDispatch;