I created a survey page, but when someone doesn't have credits I want to show a notification to the user using react-notifications, I've already tested the button and standalone it works, but when I added it to the tag using react-router-dom on an onClick event, the functions runs, but the notifications doesn't appear. Here's the code:
import React, { Component } from 'react';
import 'react-notifications/lib/notifications.css';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import {NotificationContainer, NotificationManager} from 'react-notifications';
class Button extends Component {
createNotification = () => {
return () => {
switch (this.props.auth.credits) {
case 0:
console.log(this.props.auth.credits);
NotificationManager.error('You have no credits', 'Click to close!', 5000, () => {
});
break;
}
};
};
render() {
return (
<div>
<div className="fixed-action-btn">
<Link to="/surveys/new" className="btn-floating btn-large red" onClick={this.createNotification()}>
<i className="material-icons">add</i>
</Link>
</div>
<NotificationContainer/>
</div>
);
}
}
function mapStateToProps({ auth }){
return { auth };
}
export default connect(mapStateToProps)(Button);
So, when I test this on:
import React from 'react';
import Surveys from './surveys/Surveys';
import Button from '../utilities/addButton';
const Board = () => {
return (
<div>
<Surveys />
<Button />
</div>
);
};
export default Board;
It shows the button, and when clicked without credits, it console.logs the 0 credits, but, it just redirects to the referenced page without showing the notification created.
On my side, it doesn't appear an error neither in the terminal nor in the console or network. But still, the notification is processed but not shown.
So my question is: Is it possible to make the notification appear when the tag redirects to the new page, the only way that I see a solutions if it's not possible is making a conditional to stop the tag to make the change, am I wrong?
Thanks in advance.
Sorry if my question is not properly presented or written, is my first question here.
onClick prop for Link accept function reference. so try replacing
<Link to="/surveys/new" className="btn-floating btn-large red" onClick={this.createNotification}>
<i className="material-icons">add</i>
</Link>
This may be a Very Late reply but for those who didnt answer its because Link doesnt accept onCLick... try for html or with react or reactbootstrap package
Related
I have form with a drag and drop component where I can upload images, after this I send these pictures with axios to my backend and save it on server side and then re-render it in a preview mode. My problem is, that if a user uploads some pictures and after that he switches to another page without submitting the form the added pictures are staying on my server side for no reason.
So the question: I want to check inside my component if a user is leaving, show a prompt and if he clicks on the OK button I want to delete all the added pictures from my backend before leaving. How can I detect this?
My simplified snippet:
function MyComp(props) {
const [Images,setImages] = useState([]) // in this array I store the recieved image's URL
const [isBlocking,setIsBlocking] = useState(true) // used for prompt
const handleSubmit = (event) => {
event.preventDefault();
setIsBlocking(false)
}
return(
<Grid container className={classes.mainGrid} direction="row" spacing={2}>
<Grid item xs={4} xl={4}>
<Prompt when={isBlocking} message="There are unsaved datas. Are you sure you want to leave?"/>
<form className={classes.form} onSubmit={handleSubmit}>
... somecode
</Grid>
</Grid>
)
}
export default MyComp
Thanks in advance
Inside React Function Component you can call the prompt when the user is trying to leave , i.e when the component is unmounting
In Class Component of React you can use React componentWillUnmount() and in Function Component You can use useEffect cleanup function
Code for Function Component
import React, { useEffect } from "react";
import { Link } from "react-router-dom";
export default function Home(props) {
useEffect(() => {
return function cleanup() {
alert("unmounting");
//call api and execute your code here
};
}, []);
return (
<div>
<Link to="/home">
On Click I will unmount this component and go to /home
</Link>
</div>
</Link>
);
}
Code for Class Component
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
export default class Test extends Component {
componentWillUnmount() {
alert('unmounting component');
//call your code here
}
render() {
return (
<div>
<Link to='/home'>
On Click I will unmount this component and go to /home
</Link>
</div>
);
}
}
You can check this codesandbox if you want any ref
When you leave the page, the component method componentWillUnmount() fires. I don't recall how this behaves if you were to simply close the browser window as opposed to just navigating away, nor do I recall how you can escape it and stay on the component, but that should at least be a good starting point for you. Obviously you'd have to do a class extending React.Component for this one instead of a straight function.
I'm trying to redirect to a page using an onClick event of a component. As I have react gatsby installation is it possible to use Link from gatsby-link to redirect.
import React from 'react';
import { OverflowMenu, OverflowMenuItem } from '../Overflow';
import Link from 'gatsby-theme-carbon/src/components/Link';
class OverflowComponent extends React.Component {
editPage(index) {
console.log();
// window.location.href='/edit';
return(
<Link to="/edit"></Link> // I'm trying to redirect to Edit page
)
}
deletePage() {
console.log("Delete clicked");
}
render(){
return (
<div>
<OverflowMenu flipped={true}>
<OverflowMenuItem itemText="Edit" primaryFocus onClick={() => this.editPage()} />
<OverflowMenuItem itemText="Delete" onClick={() => this.deletePaget()} />
</OverflowMenu>
</div>
);
}
}
export default OverflowComponent;
from the above code the Overflow component is a contributed component and it can have a onClick function. And I'm trying to redirect using gatsby-link.
Instead of using Link or window.location as mentioned in the question we can use navigate from gatsby. As shown below
import React from 'react';
import { OverflowMenu, OverflowMenuItem } from '../Overflow';
import {navigate} from 'gatsby'; //import navigate from gatsby
class OverflowComponent extends React.Component {
editPage(index) {
navigate('/edit'); //navigate to edit page
}
deletePage() {
console.log("Delete clicked");
}
render(){
return (
<div>
<OverflowMenu flipped={true}>
<OverflowMenuItem itemText="Edit" primaryFocus onClick={() => this.editPage()} />
<OverflowMenuItem itemText="Delete" onClick={() => this.deletePaget()} />
</OverflowMenu>
</div>
);
}
}
export default OverflowComponent;
<Link> renders an anchor element (<a href='...'>). You would probably want to use navigate here instead: https://www.gatsbyjs.org/docs/gatsby-link/#how-to-use-the-navigate-helper-function.
You might also need to use the onClick prop on the <OverflowMenuItem> component depending on how you have that setup.
I'm working on a website about donation using Gatsby v2 (Reactjs) and I need an example like open modal window on button donation click using Gatsby or ReactJS. I search on internet and I got nothing.
Thanks in advance.
Here's a simple (Gatsby) page that makes use of react-modal as an example. In this example I've replaced the default IndexPage in the Gatsby v2's new starter site that you can generate via the CLI.
import React, { Component } from 'react'
import ReactModal from 'react-modal'
import { Link } from 'gatsby'
import Layout from '../components/layout'
ReactModal.setAppElement('#main')
class IndexPage extends Component {
constructor(props) {
super(props)
this.state = {
isModalOpen: false,
}
}
handleModalOpen = event => {
// console.log('handleModalOpen: ', event);
this.setState({ isModalOpen: true })
}
handleModalClose = event => {
// console.log('handleModalOpen: ', event);
this.setState({ isModalOpen: false })
}
render() {
return (
<Layout>
<div id="main">
<h1>Hi people</h1>
<p>Welcome to your new Gatsby site.</p>
<p>Now go build something great.</p>
<Link to="#" onClick={this.handleModalOpen}>
Donate Now
</Link>
</div>
<ReactModal
isOpen={this.state.isModalOpen}
onRequestClose={this.handleModalClose}
contentLabel="Example Modal In Gatsby"
>
<h2>Donate</h2>
<button onClick={this.handleModalClose}>Close Modal</button>
</ReactModal>
</Layout>
)
}
}
export default IndexPage
That should get you going. Best to read up on how to expand on this example using react-modal here (or use an alternative).
First of all the above example will not work because #main doesn't exist, right now the id for Gatsby app is ___gatsby, so it shoul look like this
ReactModal.setAppElement('#___gatsby')
But it's not good to hope that this id is not going to change in the future. So it's better to implement your own React modal component, here is a good example https://www.digitalocean.com/community/tutorials/react-modal-component
I'm working on a small program in React.js. I am trying to pass in a URL using {this.props}, but instead of linking to the actual webpage, the link leads to the page in localhost. I've been trying to figure out what's happening, but I can't see why the link isn't leading out.
I am building an app that generates a URL that a user clicks on, to lead straight to a jpeg/gif.
JSON URL (random pictures of dogs): https://random.dog/woof.json
Here are my codes:
App.js
import React, { Component } from 'react';
import Search from './components/Search';
class App extends React.Component {
state = {
dog_URL: undefined,
}
getDogs = async (e) => {
e.preventDefault();
const api_call = await fetch(`https://random.dog/woof.json`);
const data = await api_call.json();
const dog_url = data.url;
this.setState({
result_URL: dog_url
})
}
render() {
return (
<div className="container">
<Search
getDogs={this.getDogs}
</div>
);
}
}
export default App;
import React from 'react';
class Search extends React.Component {
render() {
return (
<form onSubmit={this.props.getDogs}>
<input type="text" name="q" placeholder="search for..." />
<br />
<Button> Search </Button>
<br />
<p> Dog link: {this.props.dog_url} </p>
</form>
)
}
}
export default Search;
Expected result: user is able to click on link
Actual result: link leads to http://localhost:3000/%7Bthis.props.dog_url%7D
Can anyone give some pointers or suggestions as to why this wouldn't be working?
<p> Dog link: {this.props.dog_url} </p>
I do not believe that "{this.props.dog_url}" needs to be quoted. Rather, simply {this.props.dog_url} ought to work given how JSX variable interpolation works. Is it possible that this might be causing the strange behavior?
In order to study the react framework, I've been developing a simple web application to rate books. It's currently looking like this:
And the idea of the side bar is simple enought: it's width will be 0 when hidden, and when I click a open menu button it will be set to another width.
The code behind it all is looking like this:
import React from 'react';
import { Link } from 'react-router-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import home from '../../image/side-nav/home.png';
import list from '../../image/side-nav/list.png';
import '../../css/SideNavBar.css'
import * as utils from '../../scripts/utils.js';
const SideNavBar = () =>{
return(
<Router>
<div>
<span className="spanOpen" onClick={utils.openNav()}>☰</span>
<div className="sidenav">
<a className='closebtn' onClick={utils.closeNav()}>×</a>
<ul>
<li>
<Link to='/'><img src={home} alt='Home' /><span className='h-item'>Home</span></Link>
</li>
<li>
<Link to='/books'><img src={list} alt='Books' /><span className='b-item'>Books</span></Link>
</li>
</ul>
<div className='sidenav-footer'>
<hr />
<small>Pelicer © 2018</small>
</div>
</div>
</div>
</Router>
);
}
export default SideNavBar;
And here is the code of the util.js file, which contains the the fucntions to change:
export function openNav() {
// document.getElementsByClassName("sidenav")[0].style.width = "315px";
}
export function closeNav() {
// document.getElementsByClassName("sidenav")[0].style.width = "0";
}
But when I run it, I get the error: TypeError: Cannot read property 'style' of undefined. It happens because it is trying to change the width of somethings that has not yet been created. What I want to do, and tried using componentDidMount, is to import the JavaScript after the HTML has been rendered, in a way that when it sets the width, the component is already there. Can someone help out in a solution?
You're calling the utils.xyz functions too soon. This:
<span className="spanOpen" onClick={utils.openNav()}>☰</span>
calls utils.openNav and uses its return value as the value of the onClick. You probably meant:
<span className="spanOpen" onClick={utils.openNav}>☰</span>
(without the ()) to just refer to the function. That will work if utils.openNav doesn't need this to refer to utils during the call. If it does need this to be utils during the call:
<span className="spanOpen" onClick={() => utils.openNav()}>☰</span>
...which defines a function and uses that function as the value of onClick.
In that case where this matters, probably better to change that functional component to a class component, create that function once, and reuse it:
class SideNavBar extends React.Component {
constructor() {
this.openNav = () => utils.openNav();
// ...
}
// ...
}
and then in render:
<span className="spanOpen" onClick={openNav}>☰</span>