Skip to content

Instantly share code, notes, and snippets.

@GuoYuefei
Created January 14, 2020 13:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GuoYuefei/d4b706732f3fd55e60e37fbecb4e807e to your computer and use it in GitHub Desktop.
Save GuoYuefei/d4b706732f3fd55e60e37fbecb4e807e to your computer and use it in GitHub Desktop.
react-redux的重实现,暂叫redux-connect吧。😂所以放在redux-connect文件夹下,import相对路径使用它吧。
// 实现一个没有怎么优化过的并且简单的高阶函数connect
import React from 'react';
import { Store } from './Provider'
export default function connect(mapStateToProps, mapDispatchToProps, mergeProps) {
if (typeof mergeProps !== "function") {
mergeProps = Object.assign;
}
return (Component) => {
class ConnectComponent extends React.Component {
static contextType = Store;
constructor(props, context) {
super(props, context);
this.store = this.props.store || this.context;
this.stateToProps = this.doMapStateToProps();
this.dispatchToProps = this.doDispatchToProps();
this.state = { store: this.doMergeProps() }
}
componentDidMount() {
this.unsub = this.store.subscribe(() => {
this.updateState();
})
}
shouldComponentUpdate(nextProps, nextState) {
// console.log("now props: ", this.props, "next props: ", nextProps);
// console.log("now state: ", this.state, "next state: ", nextState);
if (JSON.stringify(nextProps) !== JSON.stringify(this.props) || JSON.stringify(nextState) !== JSON.stringify(this.state)) {
// console.log("可以刷新")
return true;
}
// console.log("不能刷新")
return false;
}
componentWillUnmount() {
this.unsub();
}
doMapStateToProps = () => {
if(typeof mapStateToProps !== "function") {
return {}
}
return mapStateToProps(this.store.getState(), this.props || {});
}
doDispatchToProps = () => {
if (typeof mapDispatchToProps !== "function") {
if (typeof mapDispatchToProps !== "object") {
return {};
}
let dispatchProps = {};
console.log(mapDispatchToProps)
for(var key in mapDispatchToProps) {
// eslint-disable-next-line
dispatchProps[key] = (...params) => this.store.dispatch(mapDispatchToProps[key](...params))
}
return dispatchProps;
}
return mapDispatchToProps(this.store.dispatch, this.props || {});
}
doMergeProps = () => {
return mergeProps(this.doMapStateToProps(), this.doDispatchToProps(), this.props || {}, { dispatch: this.store.dispatch })
}
updateState = () => {
this.setState({
...{store: this.doMergeProps()}
})
}
render() {
return (
<Component {...this.state.store}/>
)
}
}
return ConnectComponent;
}
}
import connect from './connect';
import { Store, Provider } from './Provider';
export { connect, Store, Provider };
export default { connect, Store, Provider };
import React from 'react';
const Store = React.createContext();
Store.displayName = "redux-connect";
class Provider extends React.Component {
render() {
let props = this.props;
return (
<Store.Provider value={props.store || props.value} >
{
React.Children.map(props.children, (child, i) => {
return child
})
}
{/* {props.childern.map((v) => v)} */}
</Store.Provider>
)
}
}
export default Provider;
export {Store, Provider};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment