Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //STORE JS -----------------------------------------------------------------------------
- import React, {ReactElement, useState} from "react";
- /* Do not do this in production! Super inefficient! */
- interface IStoreState {
- episodes: string[];
- favorites: string[];
- dispatchStore: <T extends StoreStateAction>(action: T) => void;
- }
- const initialState: IStoreState = {
- episodes: [],
- favorites: [],
- dispatchStore: <T extends StoreStateAction>(action: T) => {}
- };
- //Define actions here
- enum ActionType {
- AddEpisode
- };
- interface StoreStateAction {
- type: ActionType
- }
- class AddEpisodeAction implements StoreStateAction {
- type: ActionType;
- episode: string;
- constructor(episode: string) {
- this.type = ActionType.AddEpisode;
- this.episode = episode;
- }
- }
- //Action Creation Functions Here
- export const addEpisodeAction = (episode: string): AddEpisodeAction => {return new AddEpisodeAction(episode);};
- //Global reducer
- const reducer = <T extends StoreStateAction> (state: IStoreState, action: T): IStoreState => {
- switch (action.type) {
- case ActionType.AddEpisode:
- if (action instanceof AddEpisodeAction) {
- return {
- episodes: state.episodes.concat([action.episode]),
- favorites: state.favorites,
- dispatchStore: state.dispatchStore
- }
- }
- return state;
- default:
- return state;
- }
- };
- export const Store = React.createContext<IStoreState>(initialState);
- export const StoreProvider = (props: any): ReactElement => {
- const dispatchStore = <T extends StoreStateAction>(action: T): void => {
- setStoreState((state) => reducer(state, action));
- }
- //Mutable state
- const [storeState, setStoreState] = useState<IStoreState>({episodes: initialState.episodes, favorites: initialState.favorites, dispatchStore});
- return (
- <Store.Provider value={storeState}>
- {props.children}
- </Store.Provider>
- );
- };
- //EXAMPLE USAGE ----------------------------------------------------------
- import React, { ReactElement, useContext, useState, FormEvent } from 'react';
- import {Store, addEpisodeAction} from "./Store";
- const App: React.FC = (): ReactElement => {
- const ctx = useContext(Store);
- const [episode, setEpisode] = useState<string>("");
- const onSubmit = (e: FormEvent): void => {
- e.preventDefault();
- ctx.dispatchStore(addEpisodeAction(episode));
- setEpisode("");
- };
- return (
- <React.Fragment>
- <h1>Rick and Morty</h1>
- <p>Pick your favorite episode!</p>
- <form onSubmit={onSubmit}>
- <input type="text" value={episode} onChange={(e) => setEpisode(e.target.value)}/>
- <button>Add</button>
- </form>
- {ctx.episodes.map((episode: string, i: number): ReactElement => <p key={i}>{episode}</p>)}
- </React.Fragment>
- );
- }
- export default App;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement