DEV Community

Cover image for Create signals in React with 5 lines of code !
Mayank
Mayank

Posted on

Create signals in React with 5 lines of code !

Signals are creating a buzz in the frontend ecosystem because of being simple to create, consume and understand. While frameworks like Preact, Qwik, Svelte and Angular(?) have implemented them, React seems to avoid them.

What are signals

As per Preact documentation, Signals are reactive primitives for managing application state. In React, creating and updating state is a "weird" process. You useState and destructure it. Then, to updating state you must use setState() which must receive a completely new object for re-render to happen.

With signals, you can directly modify the state value to cause re-renders. Here is a 5 line implementation of such a feature with custom hook,

function useSignal(init) {
  const [state, setState] = useState(init);
  return { 
    get mut() { return state },
    set mut(_new) { setState(_new) } //I love closures !!!
  }
}

function Counter() {
  const count = useSignal(0);
  return (<>
   <div>Counter: {count.mut}</div>
   <button onClick={() => ++count.mut}>Increment</button>
  </>);
}
Enter fullscreen mode Exit fullscreen mode

Clean and Elegant right ? This new mental modal of mutation causes re-render makes our code more readable and concise, which Svelte.js is also based on.

But there is a caveat, this works for primitives. If you have an array / object state value and try to mutate its individual property, it won't trigger the setter. You have to explicitly assign the new value (like you have to do in Svelte.js).

//display 0123.... progressively with each click of button

export function Counter() {
  const count = useSignal([0]);
  const push = () => 
    count.mut = count.mut.concat(count.mut.length)

  return (<>
    <div>Counter: {count.mut}</div>
    <button onClick={push}>Increment</button>
</>);
}
Enter fullscreen mode Exit fullscreen mode

For me, this is still a better mental model than default state-setState paradigm. I am pretty sure some Javascript wizard can use Proxy/Reflect to trigger setter for even changing individual indices of array. Do comment if you know how to. :)

Top comments (3)

Collapse
 
brense profile image
Rense Bakker

You can useReducer instead of useState to handle more complex state, but tbh this is not really signals, it's just signals-like syntax around the same react state update that will trigger a traversal of the entire component tree, so child components can decide if they need to rerender. Real signals are more specific than that. The signal should tell the specific components that are using that signal, that they need to rerender.

Collapse
 
mayankhttps profile image
Mayank

Yeah, it's like a syntactic sugar which appears like signals. I hope React implements signals at some point. :)

Collapse
 
pengeszikra profile image
Peter Vivo • Edited

Try the Qwik framework which is based on Proxy solution, plus also use JSX for view building, but use class instead className. Greatest feature is using script fraction, so just the minimal codbase rendered to FE, so it is hughe impact on page loading speed to positive direction.

My opinion the react state-setState solition is give very solid mindset for state handling. So the choice is depend on developer.