reactjssignals

React component does not react to computed signal


In the following code sample:

import React from 'react';
import { signal, computed } from '@preact/signals-react';

const App: React.FC = () => {
  const count = signal<number>(0);
  const countIsMoreThanTwo = computed<boolean>(() => count.value > 2);

  console.log('CHECKS:', count.value, countIsMoreThanTwo.value);

  return (
    <>
      <h1>Vite + React</h1>
      {countIsMoreThanTwo.value && <h2>More than 2</h2>}
      <h3>Count is more than two: { countIsMoreThanTwo }</h3>
      <button onClick={() => count.value++}>
        count is { count }
      </button>
    </>
  )
}
export default App;

And here the count updates get reflected in the JSX, but the message for when count > 2 - never shows up ...

Any idea what am I missing here?


Solution

  • It looks like you haven't followed the instructions. In React, you must use either the Babel plugin to automatically transform components or add the useSignals() hook inside every component manually that needs to subscribe to a signal.

    Here's an example of the useSignals() option:

    import React from 'react';
    import { useSignal, useComputed } from '@preact/signals-react';
    import { useSignals } from "@preact/signals-react/runtime";
    
    const App: React.FC = () => {
      useSignals();
      const count = useSignal<number>(0);
      const countIsMoreThanTwo = useComputed<boolean>(() => count.value > 2);
    
      console.log('CHECKS:', count.value, countIsMoreThanTwo.value);
    
      return (
        <>
          <h1>Vite + React</h1>
          {countIsMoreThanTwo.value && <h2>More than 2</h2>}
          <h3>Count is more than two: { countIsMoreThanTwo }</h3>
          <button onClick={() => count.value++}>
            count is { count }
          </button>
        </>
      )
    }
    export default App;
    

    Also, you cannot use signal or computed inside a component -- you must use useSignal and useComputed. Again, this is covered in the docs which you should read.