Scenario -
Default Input number in text field - 1
Listed Items -
- 1
- 6
- 11
Now as soon as I remove 1 from the text field -
List Items -
- NaN
- NaN
- NaN
Now enter 4 in the input field.
List Items -
- NaN
- NaN
- 4
- 9
- 14
Expected Behavior -
List Item should display only - 4, 9 and 14
instead of NaN, NaN, 4, 9, 14
.
Let me know what I am doing wrong here.
Code -
import React, { useState } from "react";
import List from "./List";
const ReRendering = () => {
const [number, setNumber] = useState(1);
const getList = () => [number, number + 5, number + 10];
return (
<div>
<input
type="number"
value={number}
onChange={(e) => setNumber(parseInt(e.target.value, 10))}
/>
<div>
<List getList={getList} />
</div>
</div>
);
};
export default ReRendering;
List.js
import { useEffect, useState } from "react";
const List = ({ getList }) => {
const [item, setItem] = useState([]);
useEffect(() => {
setItem(getList());
}, [getList]);
return (
<div className="list">
{item.map((x) => (
<div key={x}>{x}</div>
))}
</div>
);
};
export default List;
Working Example - https://codesandbox.io/s/gallant-gagarin-l18ni1?file=/src/ReRendering.js:0-463
Doing
setNumber(parseInt(e.target.value, 10))
will set the number state toNaN
if the input field is empty, because the empty string can't beparseInt
d.And NaN causes problems because, as the React warning says:
Duplicate NaNs cause duplicate keys.
Instead, use
valueAsNumber
, and alternate with 0 if the value doesn't exist.A better way to structure this would be to call
getList
immediately in the child, instead of using a separate state and effect hook inside it.