preactjs / signals

Manage state with style in every framework
https://preactjs.com/blog/introducing-signals/
MIT License
3.63k stars 88 forks source link

Conditional rendering with signals renders the entire component!! #486

Closed OnlinePage closed 6 months ago

OnlinePage commented 6 months ago

Hi i am trying to include @preact/signals-react in my existing react js project, glad everything worked out of the box. However when i tried to have conditional rendering with the a signal variable then it doesn't works below are some parts of large component: first signalvars.js

import { signal, computed, effect } from "@preact/signals-react";

export const TextAreaQueryvalue = signal(""); //the default state
export const TextAreaQueryvalueState = signal(false);
effect(() => {
  if (TextAreaQueryvalue.value !== "") {
    TextAreaQueryvalueState.value = true;
  } else {
    TextAreaQueryvalueState.value = false;
  }
});

Now in my main component

//.... prior imports
import { useSignals } from "@preact/signals-react/runtime";
import {
  TextAreaQueryvalue,
  TextAreaQueryvalueState,
} from "../SignalVars/signalvars.js";
import MyAnotheComponent  "./MyAnotheComponent "
const MyComponent=()=>{
  useSignals ()

return (
  <>
    {TextAreaQueryvalueState.value
      ? console.log("laudaa")
      : console.log("asdasd")}
    <MyAnotheComponent />
    {/* above MyAnotherComponent is also rendered everytime
    TextAreaQueryvalueState changes , however only the places where they
    are being used should be rendered🤔
     */}
    {!TextAreaQueryvalueState.value && (
      <MdOutlineAttachment
        className="Add_Docs"
        onClick={() => setChooseDocTypePage(!ChooseDocTypePage)}
      />
    )}
  </>
);

}
export default MyComponent;

}

What expected: On signal variable change the area where conditional rendering is applied should be rendered instead of entire component including is rendered ☹️

rschristian commented 6 months ago

This is working as intended I believe.

Unfortunately there are limitations on what we can do given React's closed-off reconciler.

Closing this out

XantreDev commented 6 months ago

Hi i am trying to include @preact/signals-react in my existing react js project, glad everything worked out of the box. However when i tried to have conditional rendering with the a signal variable then it doesn't works below are some parts of large component: first signalvars.js

import { signal, computed, effect } from "@preact/signals-react";

export const TextAreaQueryvalue = signal(""); //the default state
export const TextAreaQueryvalueState = signal(false);
effect(() => {
  if (TextAreaQueryvalue.value !== "") {
    TextAreaQueryvalueState.value = true;
  } else {
    TextAreaQueryvalueState.value = false;
  }
});

Now in my main component

//.... prior imports
import { useSignals } from "@preact/signals-react/runtime";
import {
  TextAreaQueryvalue,
  TextAreaQueryvalueState,
} from "../SignalVars/signalvars.js";
import MyAnotheComponent  "./MyAnotheComponent "
const MyComponent=()=>{
  useSignals ()

return (
  <>
    {TextAreaQueryvalueState.value
      ? console.log("laudaa")
      : console.log("asdasd")}
    <MyAnotheComponent />
    {/* above MyAnotherComponent is also rendered everytime
    TextAreaQueryvalueState changes , however only the places where they
    are being used should be rendered🤔
     */}
    {!TextAreaQueryvalueState.value && (
      <MdOutlineAttachment
        className="Add_Docs"
        onClick={() => setChooseDocTypePage(!ChooseDocTypePage)}
      />
    )}
  </>
);

}
export default MyComponent;

}

What expected: On signal variable change the area where conditional rendering is applied should be rendered instead of entire component including is rendered ☹️

If you use babel plugin - you can use @preact-signals/utils/components

![image](https://github.com/preactjs/signals/assets/57757211/541069c3-0e8d-47c0-bebb-a38f8e6c0b6d) ```tsx import { TextAreaQueryvalueState } from "../SignalVars/signalvars.js"; import MyAnotherComponent from "./MyAnotheComponent"; import { Show } from "@preact-signals/utils/components"; export const MyComponent = () => ( <> TextAreaQueryvalueState.value}> ); ```