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"));
- 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"));
- 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)