It's kind of an abstract problem to describe without code examples or without diving pretty deep into React, but let me see if I can just make something up without getting too far in the weeds. Imagine you're trying to make a ModelUpdateForm component that you can just drop in, which manages all its own state:
var ProfileUpdateForm = React.createClass({
render: function() {
return <ModelUpdateForm model={@props.user}>
// I don't actually have a reference to `form`.
// I can't have a reference to `form`.
// But I need to link state between the ModelUpdateForm and its inputs.
// Anyway, this is never going to work.
<ModelInput type="text" valueLink={form.modelValueLink("name")} />
</ModelUpdateForm>;
}
});
Weird workaround that I'm not sure is an officially sanctioned way to deal with it and fear might break in future React versions or have unintended consequences:
var ProfileUpdateForm = React.createClass({
render: function() {
return <ModelUpdateForm
model={@props.user}
do={function(form) {
// Instead of taking children, ModelUpdateForm takes a `do` function prop.
// It passes itself to `do` which give you a reference to which you can link its inputs.
return <div>
<ModelInput type="text" valueLink="form.modelValueLink("name")} />
</div>;
}}
/>;
}
});
Another idea I've been kicking around and haven't tried would be to create some sort of linker object. Here's the hypothetical end result:
var ProfileUpdateForm = React.createClass({
render: function() {
var valueLinker = new ModelUpdateForm.ValueLinker()
return <ModelUpdateForm model={@props.user} valueLinker={valueLinker}>
<ModelInput type="text" valueLink={valueLinker.linkState("name")} />
</ModelUpdateForm>;
}
});
tl;dr - The way React typically wants you to do things, ProfileUpdateForm would have to manage the state. But what I wanted to build was a reusable model-bound form component. If I have to write a lot of model-binding code every time I write a new form, then there's no point to trying to make a reusable component at all. So you start having to try weird-ish ways to get it to become feasible.
It looks like this could make use of React's context feature once #2112 [1] lands.
I have similarish form components [2] which need to do this the hacky way in the meantime (cloning [3] their children in order to pass the form prop they need all the way down):
So are you traversing the entire tree of children here? I'm familiar with cloneWithProps, but I've been wary about this technique because of how deep the components I actually want to bind could be and how much traversal it could take to find them.