Why Computed component is not re-rendering?

45 Views Asked by At

I am using legend state and trying to explore this. And I didn't understand why the <Computed></Computed> component is not re-rendering on state change.

Here is my code.

import {Computed, Show, useObservable} from '@legendapp/state/react'
import { useInterval } from '../utils/hooks'

function LegendStateModal() {
    const showChild = useObservable(false)
    // const text = useComputed(() => showChild.get() ? 'true' : 'false')
  
    useInterval(() => {
      showChild.set((v) => !v)
    }, 1000)
  
    return (
      <div className='flex flex-col'>
        <span>Showing child: </span>
  
        <Computed>
          <span
            className={showChild.get() ? 'text-red-900' : 'text-green-900'}
          >
            {showChild.get() ? 'true' : 'false'}
          </span>
        </Computed>
  
        <Show if={showChild}>
          <div>Child element</div>
        </Show>
      </div>
    )
  }

  export default LegendStateModal;

I am expecting that on every second the showChild state will be toggled. And after the state changed

<Show if={showChild}>
    <div>Child element</div>
</Show>

will re-rendered. Which is doing fine.

But

<Computed>
     <span
      className={showChild.get() ? 'text-red-900' : 'text-green-900'}
     >
       {showChild.get() ? 'true' : 'false'}
    </span>
</Computed>

is not.

As it should be based on documentation: legendapp state docs

Code: codesandbox

1

There are 1 best solutions below

0
Konrad On

The child of the Computed component must be a function:

<Computed>
 {() =>
    <span
      className={showChild.get() ? 'text-red-900' : 'text-green-900'}
      >
      {showChild.get() ? 'true' : 'false'}
    </span>
  }
</Computed>

Edit:

They are using a babel plugin to achieve this behaviour https://legendapp.com/open-source/state/fine-grained-reactivity/#optionally-add-the-babel-plugin