Open christopherjbaker opened 5 years ago
which may become outdated if you edit the above
In the Providing the Data -> function section, points3
and 4
seem odd and out of place as written.
Now because I helped come up with these ideas, I know why they are there, and why they are important, but just tacking them on to the Providing the Data section is confusing, they probably require their own section and explanation with some examples.
Is there a use case for exposing this?
The use case is the same as the previous ylems @observe
decorator. If you pass an observable store instance down into some "deeper" react components it could possibly offer a performance boost by tying the "deep component" to an observer, so that changes may only cause the "deep component" to re-render, not the component with the store instance created with the hook (because we set up an observer in the useYlemStore
).
This would probably be worth having, and documenting as a solution to like the "only update one item in a list" problem.
This could be an issue of its own. It's not really limited to hooks, though more attractive with the hook usage, and it could have more details and examples of usage.
Honestly I don't see a problem keeping our v2 code in, especially if it can be tree shaken, and allow the old usage alongside of hooks, but lets deprecate the Class, HoC and Render Prop stuff and just say "You should switch to hooks". And give limited support to the old features.
Hooks are the bomb, this needs to be done sooner than later.
I like the two step approach (separation of create
and use
) primarily because I like the flexibility to test the store separately from the view.
The rest I know basically 0 about, so I will leave that up to better individuals than I.
Nice job.
@mjstahl You can test the store independently of the view even with a 1 step process. You can't test the hook directly like that, but you wouldn't need to, since ylem tests the hooks.
Hooks is direction that React is going, regardless of any issues that some of us might have with them.
The API inspiration for our current project comes from recompose and redux; the recompose library is being discontinued in favor of hooks, and one of the primary redux developers was on the hooks project in order create redux-replacement hooks like
useReducer
. While redux is not being discontinued, it is no longer necessary. For this reason, I propose that we release ylem v3 that primarily supports hooks, though old apis are maintained and decprecated atylem/legacy
.After reviewing how hooks work, I think doing this would greatly simplify the code base, as we are no longer mucking with React internals. It might be possible to support a similar api as before, though it would remove a lot of these improvements.
Ylem will only have a future if it supports hooks. To that end, there are two decisions that need to be made regarding hook implementation.
Providing the
Store
The
Store
class must be provided to the hook in some manner. This can either be a 1 step process or a 2 step process:1 step
The benefit here is simplicity: It is a single line.
2 step
This separates the above line into two line. The first could be in the component, or it could be exported by the Store file itself (asa
import { useStore } from './store'
). In that case, the benefit is that all ylem-specific code is nowhere near the component; the component just gets data from a hook and doesn't need to know how it works.Providing the Data
Data will need to be provided to ylem, for initializing and updating the store; this will most likely come from
props
. For simplicity, I will assume option 2 above.props
I propose that the primary method is for the hook to take props. In lieu of other configuration, the props would be used for initializing the store and changes to props will be diffed and those patches will be applied to the store.
As is the standard with
useEffect
and other hooks, we should accept a second argument that is used for validating if the store needs to be updated. This can simply be proxied to the underlyinguseEffect
call, so it should require very little work on our end.Function
I propose that the same hook can also take a function. This function would be called with the current store instance. This function can do some combination of three things:
const store = useStore((store) => { store.name = props.name; })
const store = useStore(() => ({ data: props }))
Additional Pieces
Observing without creating a store
Whether or not this is exposed to user-land, there will be a hook which just handles the observing/rerendering. This takes no data and returns no data. Is there a use case for exposing this?
Model Provider
Many react projects make use of providers, allow some piece of information to be defined at a level higher than it is consumed. One possibility in our case is to have a
ModelProvider
.It would look something like this, allowing one to use a string in place of a store constructor. This would work with either method of providing the store constructor.