effector / reflect

Easily render React components with everything you love from ☄️ effector.

Home Page:https://reflect.effector.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RFC: Pass component props to `mounted` hook

evist0 opened this issue · comments

It would be great if the mounted hook had props support. Trigger an event by passing incoming props to it.

type ComponentProps = {
    foo: string
    bar: boolean
}

const $bar = createStore(false);
const mounted = createEvent<ComponentProps>()

const Component: FC<ComponentProps> = ({foo, bar}) => ...

const ComponentReflected = reflect({
    view: Component,
    bind: {
        bar: $bar
    },
    hooks: { mounted }
})

<ComponentReflected foo="awesome"/>

mounted.watch(console.log) // { foo: "awesome", bar: false }

This would simplify the code, since now we have to make a separate gate in Component for such a case.

Another, more realistic case:

const mounted = createEvent<{id: string}>();

// Perform some logic to get data
const requestFx = createEffect(({ id }) => someFetch(id));

sample({
    clock: mounted
    target: requestFx
});

const $loading = createStore(false)
    .on(mounted, () => true)
    .on(requestFx.finally, () => false);
                                
const Component = reflect({
  if: $loading,
  then: Loader,
  else: View,
  hooks: { mounted }
})

Hello!

Looks pretty logical to me - lets do it, will be happy to look at your PR!

Some thoughts on the implementation:

  1. The implementation itself will be pretty straightforward, since all @effector/reflect operators are reusing the basic reflect under the hood and there is a pretty obvious point to add props into a hook call
    React.useEffect(() => {

The "ssr" part of the package is deprecated, since "no-ssr" is now isomorphic actually (i.e. works with ssr too), so tests in

describe('hooks', () => {
will be enough

  1. The typings are different though:
    public types of @effector/reflect are stored separately from the package:
    https://github.com/effector/reflect/blob/master/public-types/reflect.d.ts
    and also there are type-tests for those public types:
    https://github.com/effector/reflect/blob/master/type-tests/types-reflect.tsx

Given that current behavior of hooks is a void value in the arguments - void-typed Effector events should also still be appliable without warning from TS 🤔

So PR should also add:

  • type tests for the new case with events, that are expecting props (either full object or partially)
  • type tests for original case with events that are void-types (because i forgot to add those 😅)