preactjs / signals

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

Modify a signal in the constructor of root component will throw an error #574

Closed xymopen closed 3 months ago

xymopen commented 3 months ago

Environment

{
  "dependencies": {
    "@preact/signals": "^1.2.3",
    "preact": "^10.19.6",
  }
}

To Reproduce

import { Component, render } from 'preact'
import { signal } from "@preact/signals"

const value = signal('')

export default class App extends Component {
  constructor() {
    super()

    if (value.value == '') {
      value.value = "preact"
    }
  }

  render() {
    return <input
      value={value.value}
      onInput={event => value.value = event.currentTarget.value}
    />
  }
}

render(<App />, document.getElementById('app')!)

Error: Uncaught (in promise) TypeError: o.__ is null

Note

Remove signal modification from constructor can suppress the error.

Wrap <App /> in another component can also suppress the error.

-render(<App />, document.getElementById('app')!)
+const Wrapper = () => <App />

+render(<Wrapper />, document.getElementById('app')!)
XantreDev commented 3 months ago

I am not sure that signals support usage with class component, but certainly it shouldn't throw with such strange error

rschristian commented 3 months ago

I am not sure that signals support usage with class component

We absolutely do. Unlike React, class components are first-class citizens in Preact and we've advertised their usage with signals numerous times on Twitter.

JoviDeCroock commented 3 months ago

Modifying state in the constructor is discouraged in general though, would be better to leverage a lifecycle for these I reckon 😅 i.e. like this https://stackblitz.com/edit/vitejs-vite-t6wyct?file=src%2Fmain.tsx,package.json,src%2Findex.css&terminal=dev

xymopen commented 3 months ago

I see. Feel free to close it.