Home > Net >  Achieving ReactJS like functionality with plain JavaScript - no idea how to make the code less verbo
Achieving ReactJS like functionality with plain JavaScript - no idea how to make the code less verbo

Time:10-24

As an exercise, I wanted to create a useEffect, useState functionality from React.

I achieved similar functionality but I don't like this part of the code:

function Comp() {
  let store = new Store();
  let [a, setA] = useState(10, store);
  let [b, setB] = useState(15, store);

Basically, each time I create a new "component" I need to create a store. Global store doesn't work because I would need to send additional data when setting new state value ( setValue(value, "KEY") ).

Is there a design pattern or something that I could use to achieve what React does? The only thing that comes to mind is writting sort of a transpiler, but it seems like an overkill and like I am missing something.

Link to the sandbox:

https://codesandbox.io/s/sweet-artem-wi2imw?file=/src/store.js

EDIT:

The question is how to avoid passing the store to each newly created component.

EDIT 2:

Functionality I want to achieve:

  1. I create a "component"
  2. Make use of the useState hook to get [ getter, setter ] = useState(value)
  3. Each time a setter is called, the useEffect inside that component should be called, or more precisely it should check with store if it should be called.
  4. There would be numerous components, calling setValue(value) from component A should not trigger a callback effect in component B (why global store doesn't work, unless i provide additional arguments on a setter to let the store know which callbacks it should run

CodePudding user response:

If you are sure not to write a transpiler yourself, try decorator pattern, but it only saves your time on new Store, you still need send it manually:

// something like this:
@withNewStore
function Comp(store) {
  let [a, setA] = useState(10, store);
  let [b, setB] = useState(15, store);

However, if you are sure you only need useState and useEffect, you can do it more wildy:

// something like this:
@withHooks
function Comp({useState,useEffect)) {
  let [a, setA] = useState(10);
  let [b, setB] = useState(15);

But keep in mind that the decorator spec is still on stage2 and will be likely to be changed in the future. It's not recommanded to use it in production.

More on this decorators in typescript

CodePudding user response:

I opted for the following solution, per @bbbbbbbboat suggestion

function decorate(fn) {
  let store = new Store();
  let props = {
    useEffect: useEffectBuilder(store),
    useState: useStateBuilder(store)
  };

  return fn(props);
}

function App() {
  decorate(Comp);
  decorate(Comp2);
}

function useStateBuilder(store) {
  return (value) => {
    return useState(value, store);
  };
}

function useEffectBuilder(store) {
  return (f, deps) => {
    return useEffect(store, f, deps);
  };
}

Usage:

  function Comp({useState,useEffect)) {
      let [a, setA] = useState(10);
      let [b, setB] = useState(15);
  • Related