DEV Community

priolo22
priolo22

Posted on • Edited on

REACT and STORE with HOOKS

A medium-large project MUST use STORE because:

  • VIEW separated from the MODEL
  • You can create reusable STORES to apply to different VIEWS
  • VIEW clean from code
  • NO passing parent-child events e NO long PROPS
  • Resources accessible from anywhere in the program
  • Centralized resources that are easy to maintain
  • Simplification of tests thanks to STATE

... MUST use the STORES !!!
Let's do it the way we like it:
without using a ton of frameworks!


Centralized management of DATA SOURCE

We want a DATA SOURCE accessible from any COMPONENTS
So: let's use PROVIDERS!
REACT has them, it would be rude not to

import React, { useContext, useState } from "react";
import ReactDOM from "react-dom";

// create CONTEXT
const MyContext = React.createContext();

// component that modifies the DATA SOURCE
function ChangeSource() {
    const [value, setValue] = useContext(MyContext);
    return <button onClick={(e) => setValue("value changed")}>Change</button>;
}

// component that displays the DATA SOURCE
function ShowSource() {
    const [value, setValue] = useContext(MyContext);
    return <div>{value}</div>;
}

// APPLICATION
function App() {
    // create DATA SOURCE
    const [value, setValue] = useState("start value");

    // application
    return (
        // instantiate CONTEXT
        <MyContext.Provider value={[value, setValue]}>
            {/* modify DATA SOURCE */}
            <ChangeSource />
            {/* view DATA SOURCE */}
            <ShowSource />
        </MyContext.Provider>
    );
}

ReactDOM.render(<App />, document.querySelector("#app"));
Enter fullscreen mode Exit fullscreen mode

codesandbox

  • I create CONTEXT and DATA SOURCE
  • I insert the DATA SOURCE in the CONTEXT
  • I insert the CONTEXT in the APP (as PROVIDER)
  • And now I can access CONTEXT from any COMPONENT!
  • Once the CONTEXT has been obtained I can modify the DATA SOURCE
  • Changes are notified to the COMPONENTS that display the DATA SOURCE

All very nice!


Hook useReduce

For complexities greater than a single variable
it is convenient to use REDUCERS

import React, { useContext, useReducer, useState } from "react";
import ReactDOM from "react-dom";

// create CONTEXT
const MyContext = React.createContext();

// component that modifies the DATA SOURCE
function ChangeSource() {
    const [state, dispatch] = useContext(MyContext)
    const setValue1 = state => ({ ...state, value1: `${state.value1} changed`})
    const setValue2 = state => ({ ...state, value2: `${state.value2} changed`})

    return (<div>
        <button onClick={(e) => dispatch(setValue1)}>
            Change 1
        </button>
        <button onClick={(e) => dispatch(setValue2)}>
            Change 2
        </button>
    </div>);
}

// component that displays the DATA SOURCE
function ShowSource() {
    const [state, dispatch] = useContext(MyContext);
    return (<div> <div>{state.value1}</div><div>{state.value2}</div> </div>)
}

// simple reducer multipurpose :)
const reducer = (state, action) => action(state)

// APPLICATION
function App() {
    // create REDUCER (DATA SOURCE and DISPATCH)
    const [state, dispatch] = useReducer(reducer, {
        value1: "value 1",
        value2: "value 2"
    });

    // application
    return (
        // instantiate CONTEXT
        <MyContext.Provider value={[state, dispatch]}>
            {/* modify DATA SOURCE */}
            <ChangeSource />
            {/* view DATA SOURCE */}
            <ShowSource />
        </MyContext.Provider>
    );
}

ReactDOM.render(<App />, document.querySelector("#app"));
Enter fullscreen mode Exit fullscreen mode

codesandbox

  • I replace "useState" with "useReducer"
  • Now I can "share" thanks to CONTEXT: STATE and DISPATCH
  • STATE contains a DATA SOURCE more structured
  • DISPATCH allows you to modify STATE with "pure functions"
  • The REDUCER simply passes the DATA SOURCE to the DISPATCH

that's all! You just have to "put in order"


Let's put it in order

  • Components are defined in external files
  • The STORE is defined in store.js

...easy


Use the STORE outside of REACT

Sooner or later it will happen! So it's best to think about it right away

  • I make the REDUCER global
  • When needed I apply the REDUCER to the STORE

Useful when I have some AJAX stuff and I have to put it in the STORE
(and I am not in a REACT-COMPONENT: no hook!)


Multi STORE

  • In the COMPONENTS (VIEW) THERE IS NO CODE !!! But only LOVE for the STORE

Yes I know: it looks like VUEX... I like VUEX!

(Forgive my bad English)

Top comments (0)