I am trying to build a todo list app.The items will be kept as state variables in App.js and then this state variable are passed to another component (ItemDisplay) that will display it. But whenever I add an item to the state, the component ItemDisplay is not updating. What am I doing wrong?
App.js
import './App.css';
import { useEffect, useState } from 'react';
import Textarea from './textArea';
import ItemDisplay from './itemDisplay';
function App() {
const [items,setItems] = useState([])
const addText = (e,val)=>{
// const tempval = items
// setItems(tempval.push(val))
// console.log(items)
var newarr = items
newarr.push(val)
setItems(newarr)
// console.log(items)
// console.log(newarr)
}
return (
<div className="container">
<div className="heading">
<h2>Todo list</h2>
</div>
<Textarea addText={addText}></Textarea>
<ItemDisplay items={items}></ItemDisplay>
</div>
);
}
export default App;
ItemDsiplay.js
const items = props.items
//console.log(props.items)
return (
<div>
{items.map(item=>(<p>item</p>))}
</div>
);
}
export default ItemDisplay;
TextArea.js
const Textarea = (props) => {
const [todoVal, setTodoval] = useState('')
return (
<div className="textportion">
<input
type="text"
value = {todoVal}
onChange={(e)=>setTodoval(e.target.value)}
placeholder="Enter the list here">
</input>
<button onClick={(e)=>{props.addText(e,todoVal)}}>Add</button>
</div>
);
}
export default Textarea;
CodePudding user response:
I think you keep the array reference in app component so the child component would not update, update item array in immutable way
const addText = (e,val)=>{
var newarr = newarr.concat([val])
setItems(newarr)
}
CodePudding user response:
In your ItemDisplay.js, you are assigning props.items to a variable. This happens only once. First of all for the component to update automatically you need to assign props.items to a state variable using useState hook. If you need to update the component every time props.items changes, you need to use the useEffect hook:
const [items, setItems] = useState([])
useEffect(()=>{
setItems(props.items)
}, [props.items])
return (
<div>
{items.map(item=>(<p>item</p>))}
</div>
);
Try this in your ItemDisplay.js component. Please import useState and useEffect hooks in the component.