I wanted to display a pop up notification whenever there is a message from server . here is a implementation of popup notification
import React, { useRef, useEffect } from "react";
import { X } from "react-feather";
import { useTransition } from "@react-spring/web";
import { Message, Button, Content, Life } from "./styles";
let id = 0;
import React, { useRef, useEffect } from "react";
import { X } from "react-feather";
import { useTransition } from "@react-spring/web";
import { Message, Button, Content, Life } from "./styles";
let id = 0;
export function MessageHub({ children, timeout = 3000 }) {
const refMap = useRef(new WeakMap());
const cancelMap = useRef(new WeakMap());
const [items, setItems] = React.useState([]);
const transitions = useTransition(items, {
from: { opacity: 0, height: 0, life: "100%" },
keys: (item) => item.key,
enter: (item)
export function MessageHub({ children, timeout = 3000 }) {
const refMap = useRef(new WeakMap());
const cancelMap = useRef(new WeakMap());
const [items, setItems] = React.useState([]);
const transitions = useTransition(items, {
from: { opacity: 0, height: 0, life: "100%" },
keys: (item) => item.key,
enter: (item) => async (next, cancel) => {
cancelMap.current.set(item, cancel);
await next({ opacity: 1, height: refMap.current.get(item).offsetHeight });
await next({ life: "0%" });
},
leave: [{ opacity: 0 }, { height: 0 }],
onRest: (_, ctrl, item) => {
setItems((state) => state.filter((i) => i.key !== item.key));
},
config: (_, index, phase) =>
phase === "enter" && index === "life"
? { duration: timeout }
: { tension: 125, friction: 20, precision: 0.1 },
});
useEffect(() => {
children((msg) => {
setItems((state) => [...state, { key: id++, msg }]);
});
}, []);
return (
<>
{transitions(({ life, ...style }, item) => (
<Message style={style} key={item.key}>
<Content ref={(ref) => ref && refMap.current.set(item, ref)}>
<Life style={{ right: life }} />
<p>{item.msg}</p>
<Button
onClick={(e) => {
e.stopPropagation();
if (cancelMap.current.has(item) && life.get() !== "0%")
cancelMap.current.get(item)();
}}
>
<X size={18} />
</Button>
</Content>
</Message>
))}
</>
);
}
and its working fine as i checked with and it rendered a test notification on initial render.
<MessageHub timeout={3000}> {(add) => { add("Test notification"); }} </MessageHub>
But when i make it to render when ever there is server response . it does nothing even after successful message from server . Here is implementation of it .
const SendButton = ({ updateServerResponse }) => {
const { configuration, updateConfiguration } = useConfig();
const handleClick = async () => {
console.log(configuration);
try {
let POST_URL =
import.meta.env.VITE_BASE_URL + import.meta.env.VITE_SEND_PASTE;
const response = await axios.post(POST_URL, configuration);
if (response.status === 201) {
console.log(response.data);
updateServerResponse(response.data); // update on server response
} else {
console.error(response);
}
} catch (error) {
console.error("Error sending POST request:", error);
}
};
return (
<>
<button onClick={handleClick}>Send</button>
</>
);
};
export const Header = () => {
const [serverResponse, setServerResponse] = useState(null);
const updateResponse = (message) => {
setServerResponse(message);
};
return (
<>
<div className="header">
<ExpiryTime></ExpiryTime>
<DocFormat></DocFormat>
<PasswordInput></PasswordInput>
<SendButton updateServerResponse={updateResponse} />
<MessageHub timeout={3000}>
{(add) => {
add(serverResponse);
setServerResponse(null);
}}
</MessageHub>
{/* <MessageHub timeout={3000}>
{(add) => {
add("Test notification"); // Works ..
}}
</MessageHub> */}
</div>
</>
);
};
I wanted to know why there is no notification , even though i updated the state .Do i need to do differently .
