I wanted to make a notification component but ran into some issues.
First of all, I didn't notice the bug, because I set the array, and didn't push to it. I can confirm that it's pushing it to the array, but for some reason, it's not updating in React.
I already set keys as a timestamp, but still not working.
import './App.css';
import { v4 as uuid } from 'uuid';
import { React, useState } from 'react';
import { animated, Spring} from 'react-spring';
function App() {
var notifications = [
{
"identifier": new Date().getTime(),
"title": "lath",
"content": "react is good",
"type": true,
}
]
// window.addEventListener("message", (event) => {
// let data = event.data ?? undefined
// switch (data.type) {
// case "sendNotify":
// console.log(data)
// break
// }
// });
// addToNotify()
function addToNotify() {
notifications.push({
// "identifier": uuid().slice(0,8),
"identifier": new Date().getTime(),
"title": "lath",
"content": "this is a test",
"type": true,
})
console.log(notifications)
}
return [
<button key="clickBtn" onClick={() => addToNotify()}></button>,
<div key="notify-wrap" className="notify-wrapper">
{notifications.map(notif => (
// console.log(notif),
<Notification key={notif.identifier "-key"} title={notif.title} content={notif.content} type={notif.type} identifier={notif.identifier}/>
))}
</div>,
]
}
function Notification(props) {
// var key = uuid().slice(0,8)
// console.log(props)
return (
<Spring config={{duration: 500}} from={{ opacity: 0 }} to={{opacity : 1}}>
{styles =>
<animated.div key={props.identifier} className="notify-container" style={styles}>
<div key={props.identifier "-header-container"} className="notify-header-container">
<h1 key={props.identifier "-header"} className="notify-header">{props.title}</h1>
<img key={props.identifier "-header-img"} className="notify-icon" src={`img/${props.type ? "check" : "cross"}.png`}></img>
</div>
<p key={props.identifier "-content"} className="notify-text">{props.content}</p>
</animated.div>
}
</Spring>
);
}
export default App;
CodePudding user response:
You should use a useState hook to handle the notifications state, so that every time a new notification is added to the array, the useState triggers a re-render with the new state.
Change your code to:
import { v4 as uuid } from "uuid";
import { React, useState } from "react";
import { animated, Spring } from "react-spring";
const sampleNotification = {
// "identifier": uuid().slice(0,8),
identifier: new Date().getTime(),
title: "lath",
content: "this is a test",
type: true
};
function App() {
// use useState() and initialize it with your notifications array
var [notifications, setNotifications] = useState([
{
identifier: new Date().getTime(),
title: "lath",
content: "react is good",
type: true
}
]);
function addToNotify(notification) {
// change the state by appending the new notification to the previous state
setNotifications((prevNotifications) =>
prevNotifications.concat(notification)
);
console.log(notifications);
}
return [
<button
key="clickBtn"
onClick={() => addToNotify(sampleNotification)}
></button>,
<div key="notify-wrap" className="notify-wrapper">
{notifications.map((notif) => (
// console.log(notif),
<Notification
key={notif.identifier "-key"}
title={notif.title}
content={notif.content}
type={notif.type}
identifier={notif.identifier}
/>
))}
</div>
];
}
[...]
export default App;
CodePudding user response:
You should rather create a state to store your notifications in. Each time the state is updated, it'll trigger an re-render.
const [notifications , setNotifications] = useState([
{
"identifier": new Date().getTime(),
"title": "lath",
"content": "react is good",
"type": true,
}
])
const addToNotify = () => {
const notisObj = {
"identifier": new Date().getTime(),
"title": "lath",
"content": "this is a test",
"type": true,
}
setNotifications((curVal) => [...curVal, notisObj]);
}
CodePudding user response:
Thanks for your answers! I'm so thankful, was banging my head before!