DEV Community

Discussion on: Constructors in Functional Components With Hooks

Collapse
 
wolverineks profile image
Kevin Sullivan

would lazy initialization of useState work as a useSingleton
e.g.

const useSingleton = (initializer) => {
  React.useState(initializer)
}

const Foo = () => {
  useSingleton(() => {
    // only runs once
  })
  ...
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
bytebodger profile image
Adam Nathaniel Davis

Yep. That works as well!

Collapse
 
peerreynders profile image
peerreynders • Edited

A more fleshed out example:

// custom hook "use initializer"
function useInit(init, ...args) {
  const tuple = useState(null);
  const [state, setState] = tuple;

  if(state !== null) {
    return tuple;
  }

  const initState = init(setState, ...args);
  setState(initState);
  return [initState, setState];
}

// Component Parts
function initCounter(setState, startAt) {
  const increment = state => ({...state, count: state.count + 1});
  const clickHandler = () => setState(increment);

  return {
    count: Number(startAt),
    clickHandler
  };
}

// Component
function Counter({startAt}) {
  const [{count, clickHandler}, setState] = useInit(initCounter, startAt);

  return html`
    <p>
      <button onClick=${clickHandler}>Click me</button>
    </p>
    <output>You clicked ${count} times</output>
  `;
}

function App() {
  return html`<${Counter} startAt="12" />`;
}
Enter fullscreen mode Exit fullscreen mode

Gist