I'm trying to build a reusable SnackBar (little popup displaying info of what just happened) component with optional UNDO action. I would like to use it like this:
import SnackBar from "./SnackBar";
import { useState } from "react";
const MainComponent({item}) => {
const [snackBarVisible, setSnackBarVisible] = useState(false);
const [snackBarMessage, setSnackBarMessage] = useState("");
const [undoFunction , setUndoFunction ] = useState(null);
//var undoFunction = null;
const undoAddToFav = () => {
//code that removes from favorites the stuff that was just added
console.log("removed last added product from favs");
};
const undoAddToCart = () => {
//code that removes from cart the last added product
console.log("removed last added product from cart");
}
const addToCart = (item) => {
//some code
setSnackBarMessage("Item added to cart");
//HELP NEEDED HERE
//undoFunction = undoAddToCart; // this doesn't work at all (no error messages)
setUndoFunction(() => undoAddToCart()) // this executes undoAddToCart when addToCart is called and not on button press
setSnackBarVisible(true);
}
const addToFavorites = (item) => {
//some code
setSnackBarMessage("Item added to favourites");
//undoFunction = undoAddToFav ; // <== HELP NEEDED HERE
//setUndoFunction(() => undoAddToCart())
setSnackBarVisible(true);
}
const displaySnackBar = () => {
setSnackBarMessage("Some info");
setSnackBarVisible(true);
//this one has no "undo" button
}
//some other stuff
return (
//some other stuff that calls the actions above
<SnackBar snackBarMessage = {snackBarMessage} snackBarVisible = {snackBarVisible) undoFunction = {undoFunction}/>
);
};
I'd like this undo action to be optional.
export default const SnackBar = ({snackBarMessage, snackBarVisible, undoFunction}) => {
//some stuff
return (
<>
//some stuff - handle visibility, etc
//help needed here as well - how do I display the button only when the function prop is passed?
{undoFunction && <button onClick={undoFunction}>UNDO</button>}; //this doesn't work properly
<div>{snackBarMessage}</div>;
</>
);
};
I've tried useState, useCallback, useMemo, useRef to handle this and nothing seems to work. This is my first cry for help here:)
You must declare undoFunction
using useState
, ex by default null:
const [undoFunction, setUndoFunction] = useState(null)
And then use setUndoFunction(/* your new function here or null */)
.
It didn't work because if you don't use a state, React won't re-render changes.
The problem for your question starts from MainComponent
const [undoFunction , setUndoFunction ] = useState(null);
Since the value of undoFunction
is null, the button won't render at all in the child component. I mean this code.
{undoFunction && <button onClick={undoFunction}>UNDO</button>}; //this doesn't work properly
You can change it to something like this. Render the button and execute undoFunction
if that's available.
<button
onClick={() => {
if (undoFunction) undoFunction();
}}
>
UNDO
</button>
I have made a simple sandbox for this functionality. I've used an extra button for passing undo functionality. Check the code and see how you can use.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.