vazco / uniforms

A React library for building forms from any schema.
https://uniforms.tools
MIT License
1.94k stars 239 forks source link

Overriding componentDetectorContext #1296

Closed mariusrak closed 9 months ago

mariusrak commented 9 months ago

Hi, not sure, if it is bug or feature, but when you have multiple componentDetectorContext in a tree, only the closest one apply and the "request" to detect component is not propagated. So if you'd have something like

<AutoField.componentDetectorContext.Provider value={detectOneType}>
        <AutoField.componentDetectorContext.Provider value={detectAnotherType}>
                <AutoField.componentDetectorContext.Provider value={detectThirdType}>
                        <AudoFields />
                </AutoField.componentDetectorContext.Provider>
        </AutoField.componentDetectorContext.Provider>
</AutoField.componentDetectorContext.Provider>

You would get only those detected by the detectThirdType and detectOneType, detectAnotherType would not even run.

I thought I could do at least this inside the detector function:

const parent = useContext(AutoField.componentDetectorContext)?.(props, uniforms);
if (parent) {
        return parent;
}

But i get error too much recursion, which seems quite odd.

So is there any way to achieve cascading of detector contexts? Or can we find some? Thanks.

kestarumper commented 9 months ago

Hi @mariusrak,

I thought I could do at least this inside the detector function:

I tried that, and it works for me. Try the following reproduction example in CodeSandbox. Edit upbeat-elbakyan-2429zr

What is most important is that you cannot use useContext directly in the detectThirdType function, but you can use the context returned from useContext inside detectThirdType. If there will be too many rerenders, then it might be good to wrap that detector function with useCallback.

We don't plan to add this behavior as a default functionality because that would be a breaking change. It can be done using the above workaround if needed.

Also, you can just squeeze the detectThirdType, detectAnotherType, and detectOneType into a single root provider detector function. This should also be more performant. But I understand that this might be just your specific use case.

Let me know if that helped.

mariusrak commented 9 months ago

Hi, yes, the use case is for more complex composition.

Okay, it's nice that you found a solution for this. Thank You.