Control (and Control.custom) have limited flexibility / opaque behaviours by design. Whilst we can define a component to pass props to, we have limited control over what props are passed around, or how rendering takes place downstream.
"Render props" solves this issue by deferring rendering / mapping implementation details to a consumer.
I'm proposing an API that looks like:
<Control model="some.path" render={({onChange, onFocus, value, ...etc}) => (
<MyCustomInput label="something" onChange={onChange} {...etc} />
)}/>
With a render props API we defer rendering / mapping responsibilities to the user (a "cost") whilst increasing flexibility in how exactly the props we're providing are used (a benefit).
I think we can avoid API breaking changes by only implementing "render props behaviours" in a case where a function is passed as the render prop. This _should_ prevent breaking changes for existing consumers, whilst providing this API as an opt-in for new consumers who prefer it
render props are becoming more and more "idiomatic react" (alternatively "function as children" works too!) and I think this in itself is a value add.
I'm happy to take on the work of adding this if people are in to the idea. Cheers!
I am 馃挴 for this idea, would definitely simplify a lot of things.
Have at it! It shouldn't be difficult to do - all you'd have to do is pass in the fieldValue (and other things such as model) into the function, and you should be good to go.
@davidkpiano looks to me like the Errors component could benefit from a similar API. Support all the existing props, but allow a render prop as a more flexible alternative to wrapper and component. Would be happy to do this also. Any concerns?
edit: In this case the show prop might be more appropriately named "filter" or something, and it can filter whether error messages are passed in.
API example:
<Errors
model="some.model"
messages={{
required: 'Required',
length: 'Too long',
}}
filter|show|when={field => field.touched}
render={(errors, field) => (
// Pass in both errors and field? Why not?
<div>
{errors.map(error => <span>{error}</span>}
</div>
)}
/>
I'm all for render props everywhere. What I'd recommend is keeping the amount of arguments passed to these render props as small as possible - e.g., just fieldValues for <Control>, which contains everything in an object. I want to avoid positional arguments.
Most helpful comment
@davidkpiano looks to me like the Errors component could benefit from a similar API. Support all the existing props, but allow a
renderprop as a more flexible alternative towrapperandcomponent. Would be happy to do this also. Any concerns?edit: In this case the
showprop might be more appropriately named "filter" or something, and it can filter whether error messages are passed in.API example: