'Getting sane default values for input types that are dynamic
I'm having trouble figuring out the best way to set and get sane defaults for form inputs that can be different input types dynamically. Consider this example:
App.jsx:
class App extends React.Component {
constructor(props) {
super(props);
this.rowRefs = {};
this.state = {filterRows: [0, 1, 2]};
}
onButtonClick() {
const data = [];
Object.values(this.rowRefs).forEach((ref) => {
data.push(ref.getRowData());
});
// Should hold all form row input values.
console.log(data);
}
renderFilterRows() {
const rows = [];
for (let i = 0; i < this.state.filterRows.length; i++) {
const rowId = this.state.filterRows[i];
rows.push(
<FilterRow ref={(ref) => {
this.rowRefs[rowId] = ref;
}}
key={rowId} />);
}
return rows;
}
render() {
return (
<form>
{this.renderFilterRows()}
<button onButtonClick={this.onButtonClick}>Go</button>
</form>
);
}
}
and FilterRow.jsx:
export class FilterRow extends React.Component {
constructor(props) {
super(props);
this.state = {typeVal: 'foo', val: ''};
this.onSelectChange = this.onSelectChange.bind(this);
this.updateVal = this.updateVal.bind(this);
}
getRowData() {
return {typeVal: this.state.typeVal, val: this.state.val};
}
updateVal(e) {
this.setState({val: e.target.value});
}
renderOtherInput() {
if (this.state.typeVal === 'foo') {
return <input type="number" onChange={this.updateVal}/>
} else if (this.state.typeVal === 'bar') {
return (
<select onChange={this.updateVal}>
<option value="baz">Baz</option>
// ...
</select>
);
}
}
onSelectChange(e) {
this.setState({typeVal: e.target.value});
}
render() {
return (
<div>
<select onChange={this.onSelectChange}>
<option value="foo">Foo</option>
<option value="bar">Bar</option>
</select>
{this.renderOtherInput()}
<div>
);
}
}
The problem is, how do I make sure the val state inside FilterRow is actually correct at all times even if the inputs never change values? The initial empty string val state maybe makes sense if the rendered "other input" is a text/number input, but if it's a select, the default is actually just the first option in the list. I tried doing this.setState({val: ..sanedefault..}) after rendering the dynamic "other" input, but this gets into an infinite loop (expectedly).
Ideas? Thanks in advance!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
