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

Dynamic bind API #43

Open
Kelin2025 opened this issue Aug 11, 2022 · 5 comments
Open

Dynamic bind API #43

Kelin2025 opened this issue Aug 11, 2022 · 5 comments

Comments

@Kelin2025
Copy link
Member

This RFC solves impossibility to combine @effector/reflect and effector-factorio, as well as adding protocol to integrate other dynamic bindings in a future

How does it look?

It looks like this:

import { reflect, take } from '@effector/reflect'

const SomeInput = reflect({
  view: Input,
  bind: {
    value: take(something, key)
  }
})

take returns the following structure:

{
  /** Telling `reflect` how to extract the dynamic source of units */
  useSource: props => something.useSource(props),
  /** `key` that takes unit from  source */
  key: key
}

In effector-factorio we will add this alias:

factory.useSource = factory.useModel // Takes model instance from React.Context

And then we will be able to combine them:

const factory = modelFactory(() => {
  return {
    $value: createStore("")
  }
})

const SomeInput = reflect({
  view: Input,
  bind: {
    value: take(factory, "$value")
  }
})

Also

  • We should also support (source, props) => key variant for key in order to support dynamic factories (they're not welcome but technically possible)
  • We could also add fromProps(key) === take({ useSource: props => props, key) shorthand that allows to take store from just props

Why this API? Why not bind: props => ({ ... })?

  • No breaking changes
  • We still statically get all non-dynamic bindings
  • This API is not limited/specific for effector-factorio only, it doesn't even have its mention
  • Adds only 10 lines of code in @effector/reflect and 1 alias in effector-factorio
@Foprta
Copy link

Foprta commented Jun 15, 2023

There is a lot of ways in React to get dynamic data using hooks.

// Simple hook
const data = useHook();

// Hook with params
const data = useHook(params);

// Hook with callback
const data = useHook(() => new Class());

// Hook returning array
const [data] = useHook();

// Hook returning object
const {data} = useHook();

// Hook that depends on other hook data
const dataOne = useHookOne();
const dataTwo = useHookTwo(dataOne); 

Also with your implementation if you use multiple keys from the factory

  bind: {
    value: take(factory, "$value"),
    valueChange: take(factory, "valueChange")
  }

The factory useModel() will be called N times, where N is the amount of wanted keys.


It might be much more flexible to add a hook property that will gather all the data and then add it to a bind values.

const SomeInput = reflect({
  view: Input,
  bind: {
    value: $value
  },
  useDynamicBind: (componentProps) => {
    const hookWithPropsData = useHook(componentProps.transactionId);
    const hookThatDependsData = useDependentHook(hookWithPropsData);
    const {$store, storeChange} = factory.useModel();

    return { $store, storeChange, hookThatDependsData }
  }
})

@sergeysova
Copy link
Member

sergeysova commented Jun 16, 2023

What about API like this?

const SomeInput = reflect({
  view: Input,
  bind: {
    value: factory.fromModel((model) => model.$value),
  },
})

@sergeysova
Copy link
Member

But actually I think we can implement take(factory, 'key')

@Kelin2025
Copy link
Member Author

With factory.fromModel factorio will know about reflect. And we'll also have to make the same for keyval and any other library 🤔

@sergeysova
Copy link
Member

I think factory.fromModel can return some internal object implement by protocol.

{
  useSource: props => something.useSource(props),

  fn: () => Unit
}

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

No branches or pull requests

3 participants