Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: Transform useState/useEffect of ReactJS to createSignal/onCleanup of SolidJS. #1

Open
trivikr opened this issue Mar 17, 2022 · 5 comments
Labels
enhancement New feature or request

Comments

@trivikr
Copy link
Contributor

trivikr commented Mar 17, 2022

Input code

import React, { useState, useEffect } from "react";
import { render } from "react-dom";

const CountingComponent = () => {
  const [count, setCount] = useState(0);
  useEffect(() => {
    const interval = setInterval(() => setCount(count + 1), 1000);
    return () => {
      clearInterval(interval);
    };
  }, []);
  return <div>Count value is {count}</div>;
};

render(() => <CountingComponent />, document.getElementById("app"));

Expected Output

import { createSignal, onCleanup, onMount } from "solid-js";
import { render } from "solid-js/web";

const CountingComponent = () => {
  const [count, setCount] = createSignal(0);
  onMount(() => {
    const interval = setInterval(() => setCount(count + 1), 1000);
    onCleanup(() => clearInterval(interval));
  });
  return <div>Count value is {count()}</div>;
};

render(() => <CountingComponent />, document.getElementById("app"));

Additional context

Example transform to convert useState/useEffect of ReactJS to createSignal/onCleanup of SolidJS.

@trivikr trivikr added the enhancement New feature or request label Mar 17, 2022
@lxsmnsyc
Copy link

It's also interesting if we can convert "unlisted dependencies" and transform them into untrack calls. For example:

const [count, setCount] = useState(0);

useEffect(() => {
  console.log(count); // passively  read count
}, []);

into

const [count, setCount] = createSignal(0);

createEffect(() => {
  console.log(untrack(count)); // passively  read count
});

@N0tExisting
Copy link

I would actually expect the useEffect code to be placed in an onMount block:

import { createSignal, onMount, onCleanup } from "solid-js";
import { render } from "solid-js/web";

const CountingComponent = () => {
  const [count, setCount] = createSignal(0);
  onMount(() => {
    const interval = setInterval(() => setCount(count + 1), 1000);
    onCleanup(() => clearInterval(interval));
  });
  return <div>Count value is {count()}</div>;
};

render(() => <CountingComponent />, document.getElementById("app"));

@trivikr
Copy link
Contributor Author

trivikr commented Mar 21, 2022

I would actually expect the useEffect code to be placed in an onMount block

Thanks, @N0tExisting!
I've updated the issue description, and the feature request template in 021dde0

@lxsmnsyc
Copy link

I would actually expect the useEffect code to be placed in an onMount block:

Well actually it doesn't have to

@edemaine
Copy link

edemaine commented Apr 1, 2022

It's also interesting if we can convert "unlisted dependencies" and transform them into untrack calls.

I agree this would be cool. Simpler to implement though (much more "like React") would be to transform into on:

[name, setName] = useState('');
[debug, setDebug] = useState(false);
useEffect(() => {
  if (debug) console.log(`Hello ${name}!`);
}, [name]);

[name, setName] = createSignal('');
[debug, setDebug] = createSignal(false);
useEffect(on([name], () => {
  if (debug()) console.log(`Hello ${name()}!`);
}));

This seems like a natural first goal; then we can output nicer things when the list is empty or complete, or use untrack which is maybe more Solid-like. Though in both the complete and untrack case, I worry that it's hard to tell whether the code actually depends on things in the Solid sense at compile time, because of conditionals etc. Converting to on actually has the same semantics so is preferable if we want correctness (as opposed to near-correctness that requires hand-editing).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants