美文网首页
使用Context创建store

使用Context创建store

作者: pipu | 来源:发表于2019-08-07 12:54 被阅读0次

    使用Context创建Store

    createStore 文件
    import React, { createContext, PureComponent } from 'react';
    
    // 返回一个装饰器函数,参数是当前的组件函数
    const createConnect = (ContextConsumer) => (WrappedComponent) => (props) => {
        const ConnectFun = (allProps) => <WrappedComponent {...allProps} />;
        ConnectFun.staticName = `Connect(${WrappedComponent.displayName
                || WrappedComponent.name
                || 'Component'})`;
        return (
            <ContextConsumer>
                {
                    (state) => {
                        console.log(state);
                        return (
                            <ConnectFun {...state} {...props} />
                        );
                    }
                }
            </ContextConsumer>
        );
    };
    
    const createProvider = (ContextProvider, store) => (WrappedComponent) => {
        class Provider extends PureComponent {
            constructor(props) {
                super(props);
                console.log('saaa');
                this.state = {
                    ...store,
                    setStore: this.setStore,
                };
            }
    
            setStore = (state, callback) => {
                this.setState(state, callback);
            }
    
            render() {
                console.log(ContextProvider);
                console.log(this.state);
                return (
                    <ContextProvider value={this.state}>
                        <WrappedComponent {...this.props} {...this.state} />
                    </ContextProvider>
                );
            }
        }
        Provider.displayName = `Provider${WrappedComponent.displayName || WrappedComponent.name || 'component'}`;
        return Provider;
    };
    
    
    const createStore = (store) => {
        const context = createContext();
        const Provider = createProvider(context.Provider, store);
        const Connect = createConnect(context.Consumer);
        return {
            Provider,
            Connect,
            Consumer: context.Consumer
        };
    };
    
    export default createStore;
    
    
    store 文件
    import createStore from './createStore.jsx';
    
    export const { Provider, Connect, Cosumer } = createStore({
        text: 'test context',
        num: 3,
    });
    
    
    demo文件
    import React, { Component } from 'react';
    
    import { Provider, Connect } from './store.jsx';
    
    
    const Box = (props) => {
        const {
            title, fun = () => {}, num, text, children
        } = props;
        return (
            <div style={{
                border: '1px solid #ddd',
                padding: '20px',
                margin: '10px',
            }}
            >
                <div>
                    <h5>{title}</h5>
                    <p>
    当前num是
                        <span>{num}</span>
                    </p>
                    <p>
    当前text是
                        <span>{text}</span>
                    </p>
                    <button type="button" onClick={() => { fun('add') }}>增加</button>
                    <button type="button" onClick={() => { fun('minus') }}>减少</button>
                </div>
                <div style={{
                    paddingLeft: '20px',
                }}
                >
                    {children}
                </div>
            </div>
        );
    };
    
    @Connect
    class Child1 extends Component {
        clickFun = (type) => {
            this.props.setStore({
                num: this.props.num + (1 * (type === 'add' ? 1 : -1))
            });
        }
    
        render() {
            return (
                <Box
                    title="Child Component 1 每次增加/减少5"
                    {...this.props}
                    fun={this.clickFun}
                />
            );
        }
    }
    
    @Connect
    class Child2 extends Component {
        clickFun = (type) => {
            this.props.setStore({
                num: this.props.num + (1 * (type === 'add' ? 1 : -1))
            });
        }
    
        render() {
            return (
                <Box
                    title="Child Component 2 每次增加/减少5"
                    {...this.props}
                    fun={this.clickFun}
                />
            );
        }
    }
    
    @Connect
    class Parent1 extends Component {
        clickFun = (type) => {
            this.props.setStore({
                num: this.props.num + (5 * (type === 'add' ? 1 : -1))
            });
        }
    
        render() {
            return (
                <Box
                    title="Parent Component 1 每次增加/减少5"
                    {...this.props}
                    fun={this.clickFun}
                >
                    <Child1 />
                    <Child2 />
                </Box>
            );
        }
    }
    
    @Connect
    class Parent2 extends Component {
        clickFun = (type) => {
            this.props.setStore({
                num: this.props.num + (5 * (type === 'add' ? 1 : -1))
            });
        }
    
        render() {
            return (
                <Box
                    title="Parent Component 2 每次增加/减少5"
                    {...this.props}
                    fun={this.clickFun}
                >
                    <Child1 />
                    <Child2 />
                </Box>
            );
        }
    }
    
    
    @Provider
    class Page extends Component {
        changeFun = (e) => {
            const { target } = e;
            this.props.setStore({
                text: target.value
            });
        }
    
        clickFun = (type) => {
            this.props.setStore({
                num: this.props.num + (10 * (type === 'add' ? 1 : -1))
            });
        }
    
        render() {
            return (
                <Box
                    title="Page 每次增加/减少 10"
                    {...this.props}
                    fun={this.clickFun}
                >
                    <div><input type="text" onChange={this.changeFun} /></div>
                    <Parent1 />
                    <Parent2 />
                </Box>
            );
        }
    }
    
    
    export default Page;
    
    

    相关文章

      网友评论

          本文标题:使用Context创建store

          本文链接:https://www.haomeiwen.com/subject/zsrodctx.html