Search code examples
reactjssignalsrendering

React Signals does not render while UseState does


I have build my first React try-out app using UseState and am now trying to switch to React Signals in that same try-out app. Everything seems to work, I get no errors and the browser console shows data is returned, this holds true for the UseState based data as well as the UseSignals based data. However, the UseSignals based data will not render in My app. I am a novice so am probably making a beginners mistake, but I do not seem to be able to figure out what mistake. Assistance in solving this would be much appreciated!

Here's the code, please do not mind the general clumsiness of it, focus on the Signals topic is key for now.

import { useState } from 'react';
**import { useSignal } from '@preact/signals-react'**

const FamiliezSysteem = () => {

    const MWDtFeReq = **useSignal("");**
    const MWDtMwReq = **useSignal("");**

    const handleButtonClickToPingMW = async () => {
        try {
            const now = new Date();
            const offset = now.getTimezoneOffset() * 60000; 
            const localISOTime = new Date(now - offset).toISOString().slice(0, -1); 
            
            const url = `http://127.0.0.1:8000/pingAPI?timestampFE=${localISOTime}`;

            const response = await fetch(url);
            const data = await response.json();
            MWDtFeReq.value = await data[0]["FE request time"];
            MWDtMwReq.value = await data[0]["MW request time"];
 
        } catch (error) {
            console.error('Error fetching data:', error);
        }
    };
    return (
        <div>
            <div>Familiez systeem, FTW!</div>
            <button onClick={handleButtonClickToPingMW}>Ping MiddleWare</button>
            <pre> Frontend request Time= {MWDtFeReq.value} </pre>
            <pre> Middleware request Time= {MWDtMwReq.value} </pre>
        </div>

    );
};

export default FamiliezSysteem;

CoPilot gives me suggestions that are obvious not correct or seems correct but just do not work. So much for CoPilot in this case :-). So I searched the old fashioned way scowering the Internet but that did not bring ant solutions too. I started with a JSON object contained in an array (as still is the case for the data I fetch form the Database), then switched to a field per value approach (for the data I fetch from the Middleware only) without any containing structure. That did not make any difference. Then I switched the UseSignals statement arround, that did not help too. At this point in my learning curve I seem to be out of any further options, so I hope somebody can point me in the right direction. PS: In the "Review questions already on Stack Overflow to see...." the last issue seems very much the same as mine. But that dev did not use Bable or UseSignal which seemed to be the problem in that case, wehere I do use UseSignal.


Solution

  • You need to use either useSignals() or the Babel plugin w/ React. Else, the component will not react to signal updates. Instructions.

     import { useSignal } from '@preact/signals-react'
    +import { useSignals } from "@preact/signals-react/runtime";
    
     const FamiliezSysteem = () => {
    +    useSignals();
     ...
    

    It needs to be called first-thing each of your components that use signals.