Git Product home page Git Product logo

kredux's Introduction

English | 简体中文

kredux is a component that imitates redux. It implements createStore, applyMiddleware, combineReducers , and some redux middleware, i.e., thunk, logger, promise.

Usage

Create store

import { createStore, combineReducers,applyMiddleware } from "../kredux";

function counterReducer(state = 0, { type, payload }) {
    switch (type) {
        case "ADD":
            return state + payload;
        case "MINUS":
            return state - payload;
        default:
            return state;
    }

}

function counterReducer2(state = { num: 0 }, { type, payload }) {
    switch (type) {
        case "ADD2":
            return { num: state.num + payload };
        case "MINUS2":
            return { num: state.num - payload };
        default:
            return state;
    }
}

const store = createStore(
    combineReducers({
        count: counterReducer,
        count2: counterReducer2
    }),
    applyMiddleware(promise,thunk,logger)
);

export default store;

Import&Use

import React, { Component } from "react";
import store from "../store";

class ReduxPage extends Component {
    
    componentDidMount() {
		//subscribe store
        this.unsubscribe = store.subscribe(() => {
            this.forceUpdate();
        })
    }

    componentWillUnmount() {
        this.unsubscribe();
    }

    add = () => {
        store.dispatch({ type: "ADD", payload: 1 });
    }

    asyAdd=()=>{
        console.log("store.dispatch",store.dispatch);
        store.dispatch(({getState,dispatch})=>{
            console.log("dispatch",dispatch);
            setTimeout(() => {
                dispatch({type:"ADD",payload:10})
            }, 1000);
        })
    }
    
    promiseMinus=()=>{
        store.dispatch(Promise.resolve({type:"MINUS",payload:10}));
       
    }

    minus2 = () => {
        store.dispatch({ type: "MINUS2", payload: 100 });
    }

    render() {
        return (
            <>
                <h3>ReduxPage</h3>
                <div>{store.getState().count}</div>
                <button onClick={this.add}>add</button>
                <button onClick={this.asyAdd}>asy add</button>
                <button onClick={this.promiseMinus}>promiseMinus</button>
                <button onClick={this.minus2}>{store.getState().count2.num}</button>
            </>

        )
    }
}

export default ReduxPage;

Implementation

Implement Middleware

import { isFSA } from "flux-standard-action";
import isPromise from "is-promise";

function thunk({ getState, dispatch }) {
    return next => action => {
        if (typeof action === 'function') {
            return action({ getState, dispatch });
        }

        return next(action)
    }
}

function logger({getState}){
    return next=>action=>{
        console.log('====================================');
        console.log("action",action);
        console.log("preState",getState());
        let returnValue=next(action);
        console.log("curState",getState());
        console.log('====================================');
        return returnValue;
    }
}

function promise({dispatch}){
    return next=>action=>{
        if(!isFSA(action)){
            return isPromise(action)?action.then(dispatch):next(action);
        }

        return isPromise(action.payload)?
            action.payload
                .then((result)=>dispatch({...action,payload:result}))
                .catch(err=>{
                    dispatch({...action,payload:err});
                    Promise.reject(err)
                })
            :next(action);
    }
}

createStore

export default function createStore(reducer, enhancer) {
    if (enhancer) {
        return enhancer(createStore)(reducer);
    }
    let currentState;
    let currentListener = [];
    function dispatch(action) {
        currentState = reducer(currentState, action);
        currentListener.forEach(listener => listener());
    }

    function getState() {
        return currentState;
    }

    function subscribe(listener) {
        currentListener.push(listener);
        return () => {
            currentListener = currentListener.filter(item => item !== listener);
        }
    }

    dispatch({ type: "&*%#@!(<>?{}|:L:><__+(***&" })

    return {
        dispatch,
        subscribe,
        getState,
    }
}

applyMiddleware

function applyMiddleware(...funcs) {
    return createStore=>reducer=>{
        const store=createStore(reducer);
        let dispatch=store.dispatch;
        const midApi={
            getState:store.getState,
            dispatch:(action,...args)=>dispatch(action,...args),
        }
        const middlewareChain=funcs.map(middleware=>middleware(midApi));
        dispatch=compose(middlewareChain)(store.dispatch);
        return {
            ...store,
            dispatch
        }
    }
    
}

function compose(funcs) {
    if(funcs.length===0){
        return args=>args;
    }

    if(funcs.length===1){
        return funcs[0];
    }

    return funcs.reduce((a,b)=>(...args)=>a(b(...args)));
}

export default applyMiddleware;

combineReducer

export default function combineReducers(reducers) {
    return (state = {}, action) => {
        let nextState = {};
        let hasChange = false;
        for (let key in reducers) {
            const reducer = reducers[key];
            nextState[key] = reducer(state[key], action);
            hasChange = hasChange || nextState[key] !== state[key];
        }

        hasChange = hasChange || Object.keys(nextState) !== Object.keys(state);
        return hasChange ? nextState : state;
    }
}

kredux's People

Contributors

wuyuding2583 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.