Skip to content

useLayoutEffect #27

Closed
Closed

Description

@iamjohnlong

Activity

  1. ryansolid commented on May 11, 2019

    @ryansolid
    Member

    Sort of. Solid's createEffect is closer to useLayoutEffect than it is to useEffect.

    The lifecycle here is completely different. There is no lifecycle flow because the component render function only runs once. So all computations (createEffect, createMemo) run immediately and synchronous on update (or if part of a parent computation or freeze at the end of the synchronous block). What this means is Solid's effects run all synchronously and depending on dependencies and declaration order execute in that order.

    So to get effects after render like useEffect I generally just defer in a promise:

    createEffect(async () => {
      // could declare deps before the await too instead of in deps array
      await Promise.resolve();
      // Do Effect stuff
    }, [someDep])

    Technically, to get useLayoutEffect we'd want to declare an effect after render so something like this could work. Remember no Virtual DOM so elements get rendered immediately so the following works:

    const SomeComp = props => {
      const view = <div>/*... view code ...*/</div>
      createEffect(() => {
        // Do Effect Stuff
      });
      return view;
    }

    I do think this is an interesting area to see if I could handle better with the API. useEffect equivalent could just be hiding the async nature from the consumer. Maybe a createAsyncEffect but it would require explicit dependencies. createLayoutEffect I haven't had a need for as of yet. Maybe there is something I'm missing but most things that you read from the DOM after render trigger reflow anyway to get the right value, so not sure where this fits in.

    I'm definitely interested in opinions here, since as usual I have to really re-examine problems here given the differences from React.

  2. iamjohnlong commented on May 13, 2019

    @iamjohnlong
    Author

    @ryansolid Thanks for the explanation. Makes sense now. How does solids createEffect differ from React useEffect it terms of dependancies? createEffect deps need to be functions that return a bool?

    createEffect(() => {
      // do stuff...
      // What is someDep?
    }, [someDep])

    Solid is awesome btw. I would suggest updating the examples to use codesandbox.io

    https://codesandbox.io/s/r0q95159lm

  3. ryansolid commented on May 13, 2019

    @ryansolid
    Member

    Dependencies can either be implicit via tracking of accessors during effect execution or explicit like React by adding to an optional 2nd argument. In some cases it is a lot cleaner to explicitly set dependencies. So what is someDep in my example? An accessor function that your asynchronous method depends on. What is an accessor function? It's a simple thunk to wrap the fetching of tracked value. So typically it's either a Signal like those created by createSignal and createMemo, or simply a function that wraps any state access like:

    const getFirstName = () => state.firstName

    The need for a function is that we need to be sure to execute the access to value under a tracked context (ie, by the effect itself) so any time we need to define a dependency outside of the execution context of the computation we need to wrap it in a function.

    So let's pretend you needed to measure the size of the DOM element containing the users name after render whenever the firstName changes.

    You could:

    createEffect(async () => {
      // register dependency
      state.firstName;
      await Promise.resolve();
      // measure DOM element
    });

    Or you could just explicitly set a dependency:

    createEffect(async () => {
      await Promise.resolve();
      // measure DOM element
    }, [() => state.firstName])

    In most cases you will be accessing the value in the effect for a reason so it isn't necessary. I just wanted to point out that that async functions return a promise when they hit that first await so no dependencies will be made after the await statement.

    As for CodeSandBox. Completely I actually came across it recently and the ease at which I can get Solid running with a simple Parcel config is awesome. Not to mention syntax highlighting not being forced in parsing HTML script tags. The latest version of the Babel plugin doesn't even work in CodePen env anymore since it generates Import statements, so I do intend to most the examples to CodeSandBox or equivalent when I get the chance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions