Pattern for nested block components with async data
See original GitHub issueHi @ianstormtaylor! This is not as much an issue as a question around recommended pattern.
Problem:
TL;DR: So, l have a use-case of a link, which when entered turns into an embed with the following nested components which are also nested (hence can’t use isVoid
) . The data for those nested components is fetched in an async call.
<LinkEmbed>
<EditableTitle />
<EditableDescription />
</LinkEmbed>
So, the way I was set up originally was having a component for <LinkEmbed>
which would accept a url
prop. And in componentDidMount
, it would make an XHR call to pre-fill the title and description. Once the call returns, it would pass the title and children to its respective components.
Possible Solutions:
In Slate world, when I detect a url, I see two ways, second of which is not possible today.
-
setBlock
toLinkEmbed
, andinsertBlock
theEditableTitle
andEditableDescription
as well. The possible problem here would be to insert the result of the XHR call back in the components easily? I could theoretically pass thekey
of the component andonSuccess
of the XHR, update thedata
attribute of the block. -
Just
setBlock
toLinkEmbed
. Within theLinkEmbed
, be able to spread the relevant properties to each of the children.
<LinkEmbed {...attributes}>
<EditableTitle {...children.get('EditableTitle')} />
<EditableDescription {...children.get('EditableDescription')} />
</LinkEmbed>
The problem in the second solution is that there is no way to specify what block types should always comprise LinkEmbed
.
So, after this long story, I guess I am wondering if you have some guidance or pattern that you’d recommend or has worked for you in such cases. Is there a third way possible that I missed?
Thank you!
Issue Analytics
- State:
- Created 7 years ago
- Comments:6 (6 by maintainers)
Hey @oyeanuj I’m not totally sure since I haven’t done something like this before, but it seems like there are a few different considerations…
Schema
I’d probably use
schema.rules
to perform normalizations so that you ensure that aLinkEmbed
block always contains aEditableTitle
and anEditableDescription
. (I do something similar with my ownFigure
,Image
, andFigureCaption
blocks.)Here’s an internal
validation
plugin I wrote for my own use case (probably has bugs) to give you a sense for what that might look like:Emitters/Signals
It sounds like you could actually use event emitters to handle the loading case, such that when a link loads it emits an event, all of the associated blocks will
setState
when they receive that event. (They would bind and unbind incomponentDidMount
andcomponentWillUnmount
I believe.)I’ve been experimenting with using signals in a few of my components so far and it has been nice in terms of not having to worry about everything being handled in a single location.
That said, I also use the “fetch on construct” pattern too.
Here’s an example of a component that emits on hover, and then another that listens and does stuff:
Yup, that sounds right!
Addressing it in the docs somewhere sounds good to me if you find a good place.