Skip to content

Instantly share code, notes, and snippets.

@broerjuang
Created November 14, 2018 02:54
Show Gist options
  • Save broerjuang/1a5619188ba3aedbf008c8575263512a to your computer and use it in GitHub Desktop.
Save broerjuang/1a5619188ba3aedbf008c8575263512a to your computer and use it in GitHub Desktop.
Reduct (Simple implementation of Redux)
/*
Combine reducers actually a function that takes
an object that has shape
type Reducer = (state, action) => state;
{
[key: string]: Reducer
}
that return a new reducer
*/
function combineReducers(reducers) {
return (state = {}, action) => {
return Object.keys(reducers).reduce((result, key) => {
let currentReducer = reducers[key];
result[key] = currentReducer(state[key], action);
return result;
}, {});
};
}
function createStore(reducer, initialState) {
let currentReducer = reducer;
let currentState = initialState;
let listeners = [];
let isDispatching = false;
let getState = () => currentState;
let subscribe = listener => {
listeners.push(listener);
return () => {
let index = listeners.indexOf(listener);
listeners.splice(index, 1);
};
};
let dispatch = action => {
currentState = reducer(currentState, action);
listeners.slice().forEach(listener => listener());
return action;
};
dispatch({ type: "@@redux/INIT" });
return {
getState,
subscribe,
dispatch
};
}
export { combineReducers, createStore };
@broerjuang
Copy link
Author

Connect

import * as React from "react";

let Reduct = React.createContext({});

function Provider(props) {
  return (
    <Reduct.Provider value={props.store}>{props.children}</Reduct.Provider>
  );
}

// connect() is a function that injects Redux-related props into your component.
// You can inject data and callbacks that change that data by dispatching actions.
function connect(mapStateToProps, mapDispatchToProps) {
  // It lets us inject component as the last step so people can use it as a decorator.
  // Generally you don't need to worry about it.
  return function(WrappedComponent) {
    // It returns a component
    return class extends React.Component {
      static contextType = Reduct;

      constructor() {
        super(...arguments);
      }
      render() {
        let store = this.context;
        return (
          <WrappedComponent
            {...this.props}
            {...mapStateToProps(store.getState())}
            {...mapDispatchToProps(store.dispatch)}
          />
        );
      }

      componentDidMount() {
        let store = this.context;
        // it remembers to subscribe to the store so it doesn't miss updates
        this.unsubscribe = store.subscribe(this.handleChange.bind(this));
      }

      componentWillUnmount() {
        // and unsubscribe later
        this.unsubscribe();
      }

      handleChange() {
        // and whenever the store state changes, it re-renders.
        this.forceUpdate();
      }
    };
  };
}

export { Provider, connect };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment