No re-render when changing field choices
In the following example, setting the ChoiceField's choices does not cause a redraw If I force a redraw, then I see the form correctly displayed.
I expected that setChoices would do a redraw on it's own.
var React = require("react");
var forms = require("newforms");
var IPIN = forms.Form.extend({
device: forms.ChoiceField(),
});
var IPINform = new IPIN();
var Thing = React.createClass({
getInitialState: function(){
return {form: IPINform};
},
forceupdate: function(){
this.forceUpdate();
},
render: function(){
return (
<form>
<forms.RenderForm form={this.state.form} ref="ipin" />
<button>submit</button>
</form>
);
}
});
var r = React.render(<Thing/>, document.body);
setTimeout(function(){
IPINform.fields.device.setChoices(["eth0", "eth1"]);
// If I add this, it works:
// r.forceupdate();
}, 100);
A Form knows how to re-render when its state changes, but a Field currently doesn't.
Will need to provide a way to enable this automatically, but you will have to force it to update manually in the meantime.
Related: When validating the form, it doesn't re-render either.
Looking at your example a bit closer, a couple of suggestions:
- Redefining
forceUpdatemight actually beoverridingthe built-in one, so get rid of that. - You're not passing your form instance an
onChangeso it can trigger a re-render when it needs to. - If you're creating a Form instance yourself, do it inside the React component itself,like so:
getInitialState: function(){
return {
form: new IPIN({onChange: this.forceUpdate.bind(this)})
};
},
-
An alternative to creating a form instance yourself is to let
RenderFormdo it for you, by passing a Form constructor. It will also handle setting up the form instance it creates with anonChange:<forms.RenderForm form={IPIN} ref="ipin" />You can get the Form instance later like so:
this.refs.ipin.getForm()
Redefining forceUpdate might actually be overriding the built-in one, so get rid of that.
This was just a simplified version. My code didn't use that function name.
You're not passing your form instance an onChange so it can trigger a re-render when it needs to.
Uh, it seems I skipped an entire section of the docs. My bad!
Changing the code as you suggested ( forms.RenderForm form={IPIN} ) seems to work correctly, both changing the choices and showing the validation.
If I understood correctly, this should work, but it doesn't. I need to forceUpdate to see it.
var React = require("react");
var forms = require("newforms");
var IPIN = forms.Form.extend({
device: forms.ChoiceField(),
});
var Thing = React.createClass({
setthings: function(){
this.refs["ipin"].getForm().fields.device.setChoices([1,2,3,4]);
},
render: function(){
return (
<form>
<forms.RenderForm form={IPIN} ref="ipin" />
<button>submit</button>
</form>
);
}
});
var r = React.render(<Thing/>, document.body);
r.setthings();
You will still need a forceUpdate() to re-render on choice changes until this issue is resolved.