Reputation: 36209
I have the following dummy example:
function App({size}) {
const [values, setValues] = React.useState(Array(size).fill(''));
function onChange(index, event) {
console.log('setting index: ', index)
console.log('to value: ', event.target.value);
values[index] = event.target.value;
setValues(values);
}
console.log('values are');
console.log(values);
const inputs = Array(size).fill().map((_, index) => (
<input
key={`input-${index}`}
value={values[index]}
onChange={e => onChange(index, e)}
/>
));
return (
<React.Fragment>
{inputs}
</React.Fragment>
)
}
ReactDOM.render(
<App size={3} />,
document.getElementById('container')
);
I expect to be able to pass size
to App
and dynamically get that many inputs.
When I run this and type in the inputs, I see
values are
["", "", "", ""]
setting index: 3
to value: s
setting index: 1
to value: e
setting index: 0
to value: f
Looks like my component is not re-rendered. Why is that?
Upvotes: 3
Views: 5140
Reputation: 36209
As @Nick mentioned, the problem was that I was directly mutating the state itself. I ended up using the following approach (instead of Nick's approach which does work):
function onChange(index, event) {
const newValues = [...values];
newValues[index] = event.target.value;
setValues(newValues);
}
Upvotes: 2
Reputation: 16576
Your issue is most likely that you're trying to directly mutate state. In your onChange
function, you should instead make sure not to try to mutate it.
function onChange(index, event) {
const newValues = values.map((value, i) => {
return i === index ? event.target.value : value;
});
setValues(newValues);
}
Upvotes: 3