const createStore = (reducer, preloadedState, enhancer) => {
if (typeof enhancer !== 'undefined') {
return enhancer(createStore)(reducer, preloadedState);
}
let currentState = preloadedState;
let listeners = [];
const getState = () => currentState;
const subscribe = listener => {
listeners.push(listener);
return () => {
listeners = listeners.filter(l => l !== listener);
};
};
// The returned from the reducer
// inside the dispatch function
// will be the new state.
// https://github.com/reduxjs/redux/blob/master/src/createStore.ts#L246
const dispatch = action => {
currentState = reducer(currentState, action);
listeners.forEach(l => l());
};
// initialize state
dispatch({});
return {
getState,
subscribe,
dispatch,
};
};
const initialState = {
profile: null,
profiles: [],
repos: [],
loading: true,
error: {},
};
// action type constants
const GET_PROFILE = 'GET_PROFILE';
const PROFILE_ERROR = 'PROFILE_ERROR';
const GET_PROFILE_NO_STATE_COPY_RETURNED = 'GET_PROFILE_NO_STATE_COPY_RETURNED';
// reducer
const reducer = (state = initialState, {
type,
payload
}) => {
switch (type) {
case GET_PROFILE:
return {
...state,
profile: payload,
loading: false,
};
case GET_PROFILE_NO_STATE_COPY_RETURNED:
return {
profile: payload,
loading: false,
};
case PROFILE_ERROR:
return {
...state,
error: payload,
loading: false,
};
default:
return state;
}
};
const store = createStore(reducer);
const render = () => {
const html = `
<p>State</p>
<pre><code>${JSON.stringify(store.getState(), null, 4)}</code></pre>
`;
document.getElementById('app').innerHTML = html;
};
store.subscribe(render);
render();
document.getElementById('get-profile').addEventListener('click', () => {
const firstName = document.getElementById('firstName').value;
const lastName = document.getElementById('lastName').value;
store.dispatch({
type: GET_PROFILE,
payload: {
firstName,
lastName,
},
});
});
document
.getElementById('get-profile-no-state-returned')
.addEventListener('click', () => {
const firstName = document.getElementById('firstName').value;
const lastName = document.getElementById('lastName').value;
store.dispatch({
type: GET_PROFILE_NO_STATE_COPY_RETURNED,
payload: {
firstName,
lastName,
},
});
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" />
<div id="app"></div>
<input class="form-control" id="firstName" placeholder="firstName" />
<input class="form-control" id="lastName" placeholder="lastName" />
<button class="btn btn-primary" id="get-profile">GET_PROFILE </button>
<button class="btn btn-warning" id="get-profile-no-state-returned">GET_PROFILE_NO_STATE_COPY_RETURNED</button>