Passing click function from One component to other component - reactjs

In React material ui i am having two components where i am calling save function on button click, is it right way or not can anyone suggest the better way:
const callback = {};
return (
<>
{!state?.creditCard?.isSaved ? (
<Paper elevation={4} className={classes.paymentContainer}>
<Box className={classes.subPaymentContainer}>
<Typography className={classes.title}>Card Payment</Typography>
<CardPaymentForm
callback={callback}
validationPassed={() => actionsCollection.booking.saveCard(true, state.creditCard.lastFourDigits)}
formType="profileForm"
/>
<div>
<Button
type="submit"
onClick={(e) => callback.saveCard(e)}
value="SAVE CREDIT CARD"
className={classes.button}
/>
<div style={{ display: "flex", marginTop: 20 }}>
<img className={classes.lockIcon} src={lockIconInfo} alt="" />
<Typography className={classes.paymentInfo}>
<Link href="/terms" target={"_blank"}>
Terms of Payment
</Link>
.
</Typography>
</div>
</div>
</Box>
</Paper>
) : (
<div style={{ height: 373 }}>
<CardStored removeCard={removeCard} />
</div>
)}
</>
);
in CardPayementForm below calling the save function below is the code:
const CardPaymentForm = ({ classes, callback, validationPassed, formType, lastFourDigits }) {
useEffect(() => {
callback.saveCard = (e) => {
e.preventDefault();
=
if (validateForm()) {
=
validationPassed();
}
};
});
}
here without callback how to call save function directly in cardpaymentform, Any help please

I'm not sure this will apply to your problem but if you had a component_a
like
const ComponentA = ({handleClick}) => {
return(
<>
<button onClick(e => handleEvent(e))>
Click here
</button>
</>
}
and a component_b
const ComponentB = () => {
const handleClick = (e) => {
// do something with the event from component a
}
return(
<>
<ComponentA handleClick={handleClick}/>
</>
)
}

Related

When I update the data, the displayed data doesn't change even if it shows refreshing

First of all, I am developing a movie suggestion application. In this app, users can like and dislike other users' suggestions. I considered creating a structure that updates like and dislikes with buttons. I ran into a problem right here. When I update the data, the displayed data doesn't change even if it shows refreshing. If I refresh the page, the displayed data changes.
You can watch it with this link:
https://youtu.be/xi0zzNQ9HH0
How can I solve this? Thanks in advance.
const emptyForm: SuggestionForm = {
movie_name: "",
dislike_count: 0,
like_count: 0,
suggestion_by: "",
};
export default function UserMain() {
const dispatch = useDispatch();
const { data, loading, error } = useSelector(
(state: AppState) => state.suggestion
);
useEffect(() => {
dispatch<any>(getSuggestion());
}, []);
const [form, setForm] = useState<SuggestionForm>(emptyForm);
const [visible, setVisible] = useState("");
const submitForm = () => {
try {
setForm({ ...form });
dispatch<any>(addSuggestion(form));
setVisible("success");
setForm(emptyForm);
} catch {
setVisible("error");
}
};
return (
<>
<div className="main-container">
<div className="input-container">
<TextInput
value={form.movie_name}
className="input-text"
placeholder="Interstellar"
onChange={(e) => {
setForm({ ...form, movie_name: e.target.value });
}}
/>
<Button
style={{
marginLeft: "1rem",
}}
className="send-button"
primary
icon={<Send />}
onClick={() => {
submitForm();
}}
>
Send
</Button>
{visible === "success" ? (
<Notification
toast
status="normal"
title="The movie was added successfully"
onClose={() => {
setVisible("");
}}
/>
) : visible === "error" ? (
<Notification
status="critical"
toast
title="Error while adding the movie"
onClose={() => {
setVisible("");
}}
/>
) : null}
</div>
{loading ? (
<Spinner />
) : (
data.map((item) => {
return (
<div className="show-container">
<p className="movie-p">{item.movie_name}</p>
<hr />
<p className="suggest-p">{item.suggestion_by}</p>
<hr />
<p className="created-p">{item.created_at}</p>
<hr />
<Stack anchor="top-right">
<Button
style={{ marginRight: "1rem" }}
className="like-button"
primary
icon={<Like />}
onClick={() => {
const result = {
movie_name: item.movie_name,
dislike_count: item.dislike_count,
like_count: item.like_count + 1,
suggestion_by: item.suggestion_by,
};
console.log(item);
dispatch<any>(updateSuggestion(result, item.id));
}}
>
Like
</Button>
<Box background="brand" pad={{ horizontal: "xsmall" }} round>
<Text>{item.like_count}</Text>
</Box>
</Stack>
<Stack anchor="top-right">
<Button
style={{ marginRight: "1rem" }}
className="dislike-button"
primary
icon={<Dislike />}
onClick={() => {
const result = {
movie_name: item.movie_name,
dislike_count: item.dislike_count + 1,
like_count: item.like_count,
suggestion_by: item.suggestion_by,
};
console.log(item);
dispatch<any>(updateSuggestion(result, item.id));
}}
>
Dislike
</Button>
<Box background="brand" pad={{ horizontal: "xsmall" }} round>
<Text>{item.dislike_count}</Text>
</Box>
</Stack>
</div>
);
})
)}
</div>
</>
);
}

Passing function to another component getting error this is not defined react js

I am developing an app with sliding menu in react but I am getting the following error.
this is not defined
My code
Myfile
const toggleMenu = () => {
alert("clicked");
state = !state
if (state === false) {
const visibllity = "close";
alert("open")
} else {
const viisibility = "open"
alert("close")
}
}
return (
<RiderHeader toggleMenu={this.toggleMenu()} />
)
RiderHeader.js
return (
<div className="user-header">
<IconButton onClick={() => toggleMenu()}>
<MenuIcon />
</IconButton>
</div>
)
thisYou shouldn't call the function when you are declaring (or passing it as a prop).
<Component prop={this.func} /> or <Component prop={() => this.func()} />
In you file where toggleMenu is defined,
return (
<RiderHeader toggleMenu={this.toggleMenu} />
)
In RiderHeader.js,
If it's a class component then,
return (
<div className="user-header">
<IconButton onClick={() => this.props.toggleMenu()}>
{/* or
<IconButton onClick={this.props.toggleMenu}>
*/}
<MenuIcon />
</IconButton>
</div>
)
If it's a functional component,
return (
<div className="user-header">
<IconButton onClick={() => props.toggleMenu()}>
{/* or
<IconButton onClick={props.toggleMenu}>
*/}
<MenuIcon />
</IconButton>
</div>
)

How to make links work with card-img-overlay React

I'm having an issue on my project. I created a card-img-overlay to display icons over an image. If you click on the entire image you are redirected to a post. I would like to make the like and share icons clickable.
My project is in Reactjs. I am displaying images and videos from Reddit API.
Thank you for your help.
id,
slugTitle,
title,
url_overridden_by_dest,
author,
preview,
}) => {
const [isVideo, setIsVideo] = useState(false);
useEffect(() => {
if (preview) setIsVideo(preview.split('.').pop() === 'mp4');
}, [preview]);
const history = useHistory();
const goToPage = () => {
history.push(`/Post/${id}/${slugTitle}`);
};
return (
<Card
inverse
onClick={goToPage}
style={{
cursor: 'pointer',
}}
>
{isVideo && (
<video autoPlay="false" loop width="100%" src={preview}>
<track default kind="captions" />
</video>
)}
{!isVideo && (
<CardImg top width="100%" src={url_overridden_by_dest} alt={title} />
)}
<CardImgOverlay className="hideinfos">
<CardText className="w-100 d-flex justify-content-between">
<div>
<VscAccount className="mr-2" size={20} />
{author}
</div>
<div>
<LikeButtonhp
className="mr-2 card-link"
size={20}
style={{
position: 'relative',
}}
/>
<BiShareAlt size={20} />
</div>
</CardText>
</CardImgOverlay>
</Card>
);
};
You'll need to put onClick handlers on your LikeButtonhp and BiShareAlt components, and use event.stopPropagation() to stop the event from bubbling up to the <Card />:
<BiShareAlt
size={20}
onClick={event => {
event.stopPropagation();
// Do stuff for share click
}}
/>
You may need to alter the BiShareAlt and LikeButtonhp components to support an onClick prop also, for example if they render a <button> element it may look like this:
const BiShareAlt = ({ onClick }) => (
<button onClick={onClick}>
Share
</button>
);
export default BiShareAlt;
In my onClick, I added an e.stopPropagation(); and it solves my problem. Now I can click on the heart icon and it works. It stops the onClick set up on my image (parent).
function LikeButtonhp() {
const [liked, setLiked] = useState(false);
return (
<Button
outline
color="link"
className="likebutton"
onClick={(e) => {
e.stopPropagation();
setLiked(!liked);
}}
style={{ color: 'white' }}
>
{liked ? <BsHeartFill size={20} /> : <BsHeart size={20} />}
</Button>
);
}

React render not changing when calling from Button

When I click the login or register button in the following react code, the renderView() function is not rendering the Login(or the Register) component on the page.
When I log the value of e.currentTarget.value in the console, the correct values are getting logged when the button is clicked.
How do I fix this?
I want the corresponding components to be displayed when I click the Login or Register Buttons
const AppHomePage = () => {
const classes = useStyles();
const [renderVal, setRenderVal] = useState(0);
const renderView = () => {
switch(renderVal){
case 0:
return <Page />
case 1:
return <Register />
case 2:
return <Login />
default:
return <Page />
}
}
const ButtonChange = (e) => {
setRenderVal(e.currentTarget.value);
}
return(
<div>
<AppBar className={classes.root} position='static' >
<Toolbar className={classes.appbar}>
<Button className={classes.buttons} value={1} variant="contained" color="primary" onClick={ButtonChange}>
Register
</Button>
<Button className={classes.buttons} value={2} variant="contained" color="primary" onClick={ButtonChange}>
Login
</Button>
</Toolbar>
</AppBar>
<div>
{ renderView() }
</div>
<CssBaseline />
</div>
)
}
const Login = () => {
return(
<div>
<p>login</p>
</div>
)
}
const Register = () => {
return(
<div>
register
</div>
)
}
const Page = () => {
return(
<div>
page
</div>
)
}
Pass the value inside onClick function. Use an arrow function and pass the id like 1 or 2. onClick={() => ButtonChange(1)}
<Button className={classes.buttons} variant="contained" color="primary" onClick={() => ButtonChange(1)}>
Register
</Button>
<Button className={classes.buttons} variant="contained" color="primary" onClick={()=>ButtonChange(2)}>
Login
</Button>
Now in ButtonChange function get the value passed in previous step.
const ButtonChange = (id) => {
setRenderVal(id);
}
I fixed it by simply changing the cases from case 1: to case '1': and so on...

React: The onClick nested within a card is not called

I am using react hooks, and I have erased out other functions not associated with the function I am intending to call. The App functions are rendered
function App() {
const memoizedCallback = React.useCallback(() => {
console.log("Click happened");
}, []);
return (
<div className="App">
<ReactMapGl
{...viewport}
mapboxApiAccessToken={accesstoken}
onViewportChange={viewport => {
setviewport(viewport);
}}
>
{details.map(details => (
<Marker
key={details.name}
latitude={details.lat}
longitude={details.long}
>
<button
class="marker-btn"
onClick={e => {
e.preventDefault();
useselectedpark(details);
}}
>
<img src={icon} alt="icon" className="navbar-brand" />
</button>
</Marker>
))}
{selectedpark ? (
<Popup
latitude={selectedpark.lat}
longitude={selectedpark.long}
onClose={() => {
useselectedpark(null);
}}
>
<div>
<Card style={{ width: "18rem" }}>
<Card.Body>
<Card.Title>{selectedpark.name}</Card.Title>
<Card.Text>{selectedpark.postalcode}</Card.Text>
<div>
<Button variant="primary" onClick={memoizedCallback}>
Visit Gallery
</Button>
</div>
</Card.Body>
</Card>
</div>
</Popup>
) : null}
{console.log("in render", details)}
</ReactMapGl>
</div>
);
}
export default App;
the function I am intending to call is memoizedCallback. The function is called in an onClick of a button within a card.
The sequence of events is as such. A popup appears, and the user has an option to click on a button within the card that appears.
Problem: Currently, when the button is clicked right now, the function memoizedCallback is not called.
Why is that so, what did I miss here?

Resources