I'm working on an application that has a chat functionality. When a chat from new user comes in, the store will update an array of all the chats, and that array will be passed down to a child component as a prop. Any time the chats array updates, the child component runs a useEffect to perform some functions. I have following code in the child component to detect update in the chats array:
const App = (props: propsData) => {
let [filtered, setFiltered] = useState([])
let [chats, setChats] = useState({active: [], inactive: []})
useEffect(()=>{
const temp: any = {active: [], inactive: []};
props.payload.conversations.forEach((element: any) => {
const status = element.status.toLowerCase(); // element.status can be 'Active' or 'Inactive'
temp[status].push(element);
});
console.log(temp) // prints expected output: {active: [some array], inactive: [some array]}
setChats(temp); // this doesn't set the value to 'chats'
console.log(chats) // prints {active: [], inactive: []}
filterChats(); // function combines together the 'active' and 'inacive' arrays in 'chats'
// object to assign to 'filtered' array.
}, [props.payload.conversations.length])
return(
<div>
{
filtered.map((item: any) => (
<div>
//display item data here
</div>
)
)
</div
)
}
export default App;
My problem is that the setter function setChats(temp)
is not setting the value of chats
if I explicitly assign its as chats=temp
it works, but the setter method isn't working. I've tried not giving any default favlue, typecasting along with giving a default value but nothing is working.
CodePudding user response:
setState
is an async function.
So putting a console.log(state)
right after setting it will most likely show the former value, as it doesn't actually finish updating the state until the log command is run.
What you can do is add a useEffect
that has the relevant state as a dependency to check the value.
i.e -
useEffect(() => {
console.log(chats);
}, [chats]);