App顶级组件
import HomePage from './page/HomePage'
// import { Provider } from 'react-redux'
import { Provider } from './Mreact-redux'
/*
react-redux 提供两个api : Provider,connect
Provider组件 内部通过context实现跨层级传值,取到store对象;
connect 是个高阶组件,将指定的mapStateToProps、mapDispatchToProps映射到当前UI组件的props上;
从而实现 redux提供的store对象和react组件结合,数据流处理,更新视图效果。
*/
import store from './store/index'
function App() {
return (
<Provider store={store}>
<div className="App">
<HomePage />
</div>
</Provider>
);
}
export default App;
子组件-HomePage
import React from 'react'
// import { connect } from 'react-redux'
import { connect } from '../Mreact-redux'
class HomePage extends React.Component {
constructor(props) {
super(props)
this.state = {}
}
addCount = () => {
// this.props.dispatch({ type: 'ADD' })
this.props.add()
}
render() {
console.log("HomePage--props----", this.props);
const { count, minus, add } = this.props;
return (
<div>
<h1>HomePage</h1>
<h2>{count}</h2>
<button onClick={this.addCount}>add</button>
<button onClick={minus}>minus</button>
</div>
);
}
}
//connect作用:是一个高阶组件 将store对象的state映射到当前组件的props上
//接收两个参数
export default connect(
// mapStateToProps Function (state,ownProps)
state => ({ count: state }),
//mapDispatchToProps Object / Function 如果不指定mapDispatchToProps,默认props会被注入dispatch
{
add: () => ({ type: "ADD" }),
minus: () => ({ type: "MINUS" })
}
// dispatch => {
// const res = {
// add: () => dispatch({ type: "ADD" }),
// minus: () => dispatch({ type: "MINUS" })
// };
// return {
// dispatch, ...res
// }
// }
)(HomePage)
react-redux内部实现 Mreact-redux.js
import React from 'react'
// import { bindActionCreators } from 'redux';
const contextVal = React.createContext();
export const connect = (mapStateToProps, mapDispatchToProps) => WrappedComponent => {
return class extends React.Component {
static contextType = contextVal;
constructor(props) {
super(props);
this.state = {
props: {}
}
}
componentDidMount() {
//this.context 为 store对象
const { subscribe } = this.context;
this.updata();
//订阅getState变化
subscribe(() => {
this.updata();
})
}
updata = () => {
const { getState, dispatch } = this.context;
let stateProps = mapStateToProps(getState());
let dispatchProps;
if (typeof mapDispatchToProps == "object") {
dispatchProps = bindActionCreators(mapDispatchToProps, dispatch);
} else if (typeof mapDispatchToProps == "function") {
dispatchProps = mapDispatchToProps(dispatch);
} else {
//没传mapDispatchToProps -- 默认情况
dispatchProps = { dispatch };
}
this.setState({
props: {
...stateProps, ...dispatchProps
}
})
}
render() {
// console.log("this.context-----", this.context);
return <WrappedComponent {...this.state.props} />
}
}
};
export class Provider extends React.Component {
render() {
return <contextVal.Provider value={this.props.store}>{this.props.children}</contextVal.Provider>
}
}
export function bindActionCreators(creators, dispatch) {
const obj = {};
for (const key in creators) {
obj[key] = bindActionCreator(creators[key], dispatch);
}
return obj;
}
function bindActionCreator(creator, dispatch) {
return (...args) => dispatch(creator(...args));
}
redux提供的store对象
import { combineReducers, createStore } from 'redux'
const counterReducer = (state = 0, { type, payload = 1 }) => {
switch (type) {
case "ADD":
return state + payload;
case "MINUS":
return state - payload;
default:
return state;
}
};
const store = createStore(counterReducer);
export default store