How to transfer data between two child component in react js? - javascript

Actually I'm creating a front-end in which I am taking a mobile number as input on 1st page then after checking mobile number I am moving to OTP page. In OTP page I am taking otp as input and have to send both otp and mobile number to the backend. I am able to pass the otp but dont know how to pass the mobile number as I have taken it as input in the previous page.
Here is Signup Component which will take mobile number input
import React from 'react';
import './Signup.css';
class Signup extends React.Component {
constructor(props){
super(props);
this.state={
mobile:''
}
}
onMobileChange = (event) => {
this.setState({mobile: event.target.value})
}
onSubmitSignup = () => {
fetch('https://cors-anywhere.herokuapp.com/http://8080/signup/checkMobile',{
method:'post',
headers:{'Content-Type':'application/json'},
body: JSON.stringify({
mobile:this.state.mobile
})
})
.then(response => response.json())
.then(data =>{
if(data.content === 'OK'){
this.props.loadNewUser(this.state.mobile);
this.props.onRouteChange('otp','nonav');
}
})
// this.props.onRouteChange('otp','nonav');
}
render(){
const { onRouteChange} = this.props;
return(
<div className='container'>
<div className='mt6'>
<img src={require('./logo.png')} className='logoimg' alt='logo'/>
</div>
<h3 className='text-center b' style={{font:"Montserrat"}}>FOODVIRAAM</h3>
<div>
<article className="br3 ba dark-gray b--white mv4 w-100 w-50-m w-25-l mw6 shadow-6 center">
<main className="pa4 black-80">
<div className="measure">
<fieldset id="sign_up" className="ba b--transparent ph0 mh0">
<div className="mt1">
<label className="db fw5 lh-copy f3" htmlFor="email-address" style={{font:"Montserrat"}}>Enter your mobile number</label>
<input
className="pa2 input-reset ba bg-transparent hover-bg-black bw1 br2 w-100"
type="number"
name="mobile"
id="mobile"
style={{borderColor:"#ffde59",lineHeight:"28px"}}
onChange={this.onMobileChange}
/>
</div>
</fieldset>
<div className="tr">
<input
onClick={this.onSubmitSignup}
className="pv2 input-reset ba b--white bg-transparent grow pointer f3 dib" style={{font:"Montserrat"}} type="submit" value="Send OTP"/>
</div>
</div>
</main>
</article>
</div>
<h5 className="tc mt5" style={{font:"Montserrat"}}>{"#HighwayKaHygienicPitStop"}</h5>
</div>
);
}
}
export default Signup;
OTP component In which I will take OTP as input and then have to send otp and mobile number on Submit
import React from 'react';
import './Signup.css';
class Otp extends React.Component{
constructor(props){
super(props);
this.state={
otp:''
}
}
onOtpChange = (event) => {
this.setState({otp: event.target.value})
}
onSubmitOtp = () => {
console.log(this.props.mobile);
fetch('https://cors-anywhere.herokuapp.com/http://8080/signup/validateOtp',{
method:'post',
headers:{'Content-Type':'application/json'},
body: JSON.stringify({
mobile:this.props.mobile,
otp:this.state.otp
})
})
.then(response => response.json())
.then(data =>{
if(data.content === 'OK'){
// this.props.loadNewUser(this.state.otp);
this.props.onRouteChange('createprofile','nonav');
}
})
this.props.onRouteChange('otp','nonav');
}
render(){
const { mobile,onRouteChange} = this.props;
return(
<div className='container'>
<div className='mt6'>
<img src={require('./logo.png')} className='logoimg' alt='logo'/>
</div>
<h3 className='text-center b' style={{font:"Montserrat"}}>FOODVIRAAM</h3>
<div>
<article className="br3 ba dark-gray b--white mv4 w-100 w-50-m w-25-l mw6 shadow-6 center">
<main className="pa4 black-80">
<div className="measure">
<fieldset id="sign_up" className="ba b--transparent ph0 mh0">
<div className="mt1">
<label className="db fw5 lh-copy f3" htmlFor="email-address" style={{font:"Montserrat"}}>Verify OTP</label>
<input
className="pa2 input-reset ba bg-transparent hover-bg-black bw1 br2 w-100"
type="number"
name="mobile-number"
id="mobile-number"
style={{font:"Montserrat", borderColor:"#ffde59",lineHeight:"28px"}}
onChange={this.onOtpChange}
/>
</div>
</fieldset>
<div className="tr">
<input
onClick={this.onSubmitOtp}
className="pv2 input-reset ba b--white bg-transparent grow pointer f3 dib" style={{font:"Montserrat"}} type="submit" value=""/>
</div>
</div>
</main>
</article>
</div>
<h5 className="tc mt5" style={{font:"Montserrat"}}>{"#HighwayKaHygienicPitStop"}</h5>
</div>
);
}
}
export default Otp;
And this is the parent class
class App extends Component {
constructor(props){
super(props);
this.state={
route:'signup',
route1:'nonav',
newuser:{
mobile:''
}
}
}
loadNewUser = (mobile)=>{
this.setState({user: {
mobile:mobile
}})
console.log(mobile);
}
onRouteChange = (route, route1) =>{
this.setState({route:route});
this.setState({route1:route1});
}
render(){
return (
<div className="App">
{this.state.route1==='nav'
? <div>
<Navigation onRouteChange={this.onRouteChange}/>
{ this.state.route==='editmnc'
? <EditMNC parentMethod={this.onRouteChange}>{this.props.children}</EditMNC>
:<Revenue onRouteChange={this.onRouteChange}/>
}
</div>
}
: <div>
{ this.state.route==='signup'
? <Signup loadNewUser={this.loadNewUser} onRouteChange={this.onRouteChange}/>
: <div>
{ this.state.route==='otp'
? <Otp mobile={this.state.newuser.mobile} onRouteChange={this.onRouteChange}/>
: <div>
{ this.state.route==='createprofile'
? <CreateProfile onRouteChange={this.onRouteChange} />
: <div>
{ this.state.route==='signin'
? <Signin onRouteChange={this.onRouteChange} />
: <AddItem onRouteChange={this.onRouteChange}/>
}
</div>
}
</div>
}
</div>
}
</div>
}
</div>
);
}
}

Use localStorage or Cookies to store your phone number on one page and on the next page, you can easily retrieve the data by whatever medium you choose. Since storing on either of them persist your data, you don't need to worry about an accidental refresh of the page.
Don't use Redux or Context API, as they don't persist the data.
Example :-
Using the localStorage API
// storing the phone number on your first page.
localStorage.setItem('$$NAMESPACE__phone_number', phoneNumber)
// getting the phone number on your second.
const phoneNumber = localStorage.getItem('$$NAMESPACE__phone_number')

Use Redux it's a bit complicated but It is used when you need to transfer data from child to parent,
You can also get the data that you sent by props to child and got a return value
https://redux.js.org

Related

innerHTML works only once in my react app

What I am trying to do is clear my container div when the user hits the search button so all the existing search results are removed.
The problem is I am using innerHTML to clear the container div but it only works for the first time.
If you search for something for the second time then you will see no results are rendered.
I've just started learning reactjs.
Here is my code (I have removed the API key and the id just FYI).
import React from "react";
import Recipe from "./Recipe";
import "./styles.css";
export default class App extends React.Component {
constructor() {
super();
this.state = {
searchQuery: "Icecream",
searchData: [],
error: false,
loader: false
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.setState({
[e.target.name]: e.target.value
});
}
handleSubmit(e) {
e.preventDefault();
document.querySelector(".control.field").classList.add("is-loading");
this.setState({
error: false,
loader: true
});
document.querySelector(".columns").innerHTML = "test";
fetch(
`https://api.edamam.com/search?q=${
this.state.searchQuery
}&app_id=id&app_key=key`
)
.then(response => response.json())
.then(data => {
this.setState({
searchData: data.hits
});
})
.catch(err => {
this.setState({
error: true
});
})
.finally(() => {
document.querySelector(".control.field").classList.remove("is-loading");
this.setState({
loader: false
});
});
}
renderIngredients = arr => arr.map((el, index) => <li key={index}>{el}</li>);
render() {
let result;
result = this.state.searchData.map((el, index) => (
<Recipe
key={index}
image={el.recipe.image}
title={el.recipe.label}
ingredients={this.renderIngredients(el.recipe.ingredientLines)}
/>
));
return (
<div>
<form className="px-3 py-3" onSubmit={this.handleSubmit}>
<div className="field is-grouped">
<p className="control field is-expanded">
<input
className="input is-rounded"
type="text"
placeholder="Find a recipe"
name="searchQuery"
value={this.state.searchQuery}
onChange={this.handleChange}
/>
</p>
<p className="control">
<button className="button is-primary">Search</button>
</p>
</div>
</form>
{this.state.loader ? (
<div className="spinner-box">
<div className="three-quarter-spinner" />
</div>
) : (
""
)}
{this.state.error ? (
<div className="px-3 py-3">
<div className="notification is-danger">
Some error occured. Unable to fetch
</div>
</div>
) : (
<div className="columns is-multiline px-3 py-3 is-mobile">
{result}
</div>
)}
</div>
);
}
}
Recipe component :
import React from "react";
export default class Recipe extends React.Component {
render() {
return (
<div className="column is-one-quarter-desktop is-half-mobile">
<div className="card">
<div className="card-image">
<figure className="image is-4by3">
<img src={this.props.image} alt="" />
</figure>
</div>
<div className="card-content">
<p className="title is-6">{this.props.title}</p>
<ul>{this.props.ingredients}</ul>
</div>
</div>
</div>
);
}
}
What do you think about using new state for that?
What I mean is that:
this.state = {
...,
focusSearch: false
}
const handleFocus = () => {
this.setState({ ...this.state, focusSearch: true});
}
<input
className="input is-rounded"
type="text"
placeholder="Find a recipe"
name="searchQuery"
value={this.state.searchQuery}
onFocus={this.handleFocus}
onChange={this.handleChange}
/>
render() {
return (
{
focusSearch ? <div></div> : <></>;
}
)
}
I figured it out this morning. It can be done easily using conditional rending and ternary operator.
Thank you, everyone.

this.props.onAdd is not a function?

I try to nest a component with a form to add records to the database, within a component that lists everything, but pressing submit gives me this error: "Uncaught TypeError: this.props.onAdd is not a function."
I have reviewed everything from top to bottom, but I don't see the problem, since it is A method that I used before without problems, but i'm new at this, so...
I'm using Laravel in the backend (in case you need to know).
Can somebody help me please?
thanks for your time!!
This is my father component:
import React, { Component } from 'react';
import Empresa from './Empresa';
import CrearEmpresa from './CrearEmpresa';
export default class Empresas extends Component {
constructor() {
super();
this.state = {
empresas: [],
empresaActual: null
}
this.handleAddEmpresa = this.handleAddEmpresa.bind(this);
}
componentDidMount() {
fetch('/api/empresas')
.then(response => {
return response.json();
})
.then(empresas => {
this.setState({ empresas });
});
}
renderEmpresas() {
return this.state.empresas.map(empresa => {
return (
<div className="card" key={empresa.id}>
<div className="card-body">
<h5 className="card-title">{empresa.nombre}</h5>
<p className="card-text">{empresa.cif} </p>
<p className="card-text">{empresa.direccion} </p>
<p className="card-text"> {empresa.telefono} </p>
<p className="card-text"> {empresa.mail}</p>
<p className="card-text"> {empresa.entradas}</p>
</div>
<div className="card-footer">
<a onClick={()=>this.handleClick(empresa)} >Más</a>
</div>
</div>
);
})
}
handleClick(empresa) {
this.setState({empresaActual:empresa});
}
handleAddEmpresa (empresa) {
empresa.entradas = Number(empresa.entradas);
fetch( 'api/empresas/', {
method:'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(empresa)
})
.then(response => {
return response.json();
})
.then(data => {
this.setState((prevState)=> ({
empresas: prevState.empresas.concat(data),
empresaActual : data
}))
})
}
render() {
return (
<div className="container" id="empresas" >
<div className="row">
<div className="col s12 offset-m l8">
<h3> Empresas </h3>
{ this.renderEmpresas() }
</div>
<Empresa empresa={this.state.empresaActual} />
</div>
<div>
<CrearEmpresa onAdd={this.handleAddEmpresa} />
</div>
</div>
);
}
}
```````````````````````````````````````````````````````````````````````````````````````````````````
And this is the child:
```````````````````````````````````````````````````````````````````````````````````````````````````
import React, {Component} from 'react';
export default class CrearEmpresa extends Component {
constructor(props) {
super(props);
this.state = {
nuevaEmpresa: {
nombre: '',
direccion: '',
telefono: '',
mail: '',
entradas: 0
}
}
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange (e){
this.setState ({
[e.target.id]: e.target.value
})
}
handleSubmit(e) {
e.preventDefault();
console.log(this.state);
this.props.onAdd(this.state.nuevaEmpresa);
}
render() {
return(
<div>
<div className="container">
<form onSubmit={this.handleSubmit} className="transparent">
<h5 className="grey-text text-darken-3">Nueva Empresa</h5>
<div className="input-field">
<label htmlFor="nombre">Nombre</label>
<input type="text" name="nombre" id="nombre" onChange={this.handleChange} />
</div>
<div className="input-field">
<label htmlFor="direccion">Dirección</label>
<textarea className="materialize-textarea" name="direccion" id="direccion"
onChange={this.handleChange}></textarea>
</div>
<div className="input-field">
<label htmlFor="telefono">Teléfono</label>
<br />
<input type="tel" name="telefono" id="telefono" onChange={this.handleChange} />
</div>
<div className="input-field">
<label htmlFor="mail">Mail</label>
<br />
<input type="email" name="mail" id="mail" onChange={this.handleChange} />
</div>
<div className="input-field">
<label htmlFor="entradas">Número de entradas</label>
<input type="number" name="entradas" id="entradas" min="10" max="50000" step="5"
onChange={this.handleChange} />
</div>
<input type="submit" value="submit" />
</form>
</div>
</div>
)
}
}
``````````````````````````````````````````````````````````````````````````````````````````````

Submit login form made with React components

I am creating a login form with some input components and a button component.
SignIn.js
class SignIn extends Component {
render() {
return (
<article className="br2 ba dark-gray b--black-10 mv4 w-100 w-50-m w-30-l h-auto h-auto-l h-auto-m h-auto-m h-auto-ns shadow-5 center">
<main className="pa4 black-80">
<legend className="f2 fw6 ph0 mh0 tc">Sign In</legend>
<VerticalInputComponent id_name="signin_email" input_label="Email" />
<VerticalInputComponent id_name="signin_password" input_label="Password" />
<div className="tc mt3 mt3-l mt3-m mt3-ns">
<ButtonComponent button_value="Sign In" />
</div>
</main>
</article>
);
}
}
VerticalInputComponent.js
class VerticalInputComponent extends Component {
render() {
return(
<form className="pl4 pr4 pt4 pb2 black-80 w-100 measure">
<div className="measure">
<label htmlFor={ this.props.id_name } className="f6 b db mb2">{ this.props.input_label }
{ this.props.isOptional
? <span className="normal black-60">(optional)</span>
: null
}
</label>
<input id={ this.props.id_name } className="input-reset ba b--black-20 pa2 mb2 db w-100" type="text" aria-describedby="name-desc" />
</div>
</form>
)
}
}
ButtonComponent.js
class ButtonComponent extends Component {
render() {
return (
<div>
<input
className="b ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib"
type="submit"
value={ this.props.button_value }
/>
</div>
);
}
}
The question is how do I submit the email and password on a post request? I know how to do it on normal HTML but I don't know how to do it in React. I am guessing I need to use Redux or state but I don't know the syntax. The random examples that I read doesn't make sense to me at least for now.
There is no need for Redux or even a state to submit a form.
You should wrap the entire form element in a single form, even if they are nested in custom components. You had 2 forms, one for each input, but you're only wanting to send 1 signin POST request.
Also dont forget to include the name attribute in your form input elements because these are the property names the server will see in your POST request.
Note that e.preventDefault(); is to prevent the window from refreshing and we don't want that in a single-page application.
class VerticalInputComponent extends React.Component {
render() {
return(
<div className="measure">
<label htmlFor={ this.props.id_name } className="f6 b db mb2">{ this.props.input_label }
{ this.props.isOptional
? <span className="normal black-60">(optional)</span>
: null
}
</label>
<input id={ this.props.id_name } name={this.props.id_name} className="input-reset ba b--black-20 pa2 mb2 db w-100" type="text" aria-describedby="name-desc" />
</div>
)
}
}
class ButtonComponent extends React.Component {
render() {
return (
<div>
<input
className="b ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib"
type="submit"
value={ this.props.button_value }
/>
</div>
);
}
}
class SignIn extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
const data = new FormData(e.target);
for (var pair of data.entries()) {
console.log(pair[0] + ': ' + pair[1]);
}
fetch('/someURL', {
method: 'POST',
body: data,
});
}
render() {
return (
<article className="br2 ba dark-gray b--black-10 mv4 w-100 w-50-m w-30-l h-auto h-auto-l h-auto-m h-auto-m h-auto-ns shadow-5 center">
<main className="pa4 black-80">
<legend className="f2 fw6 ph0 mh0 tc">Sign In</legend>
<form onSubmit={this.handleSubmit}>
<VerticalInputComponent id_name="signin_email" input_label="Email" />
<VerticalInputComponent id_name="signin_password" input_label="Password" />
<div className="tc mt3 mt3-l mt3-m mt3-ns">
<ButtonComponent button_value="Sign In" />
</div>
</form>
</main>
</article>
);
}
}
// Render it
ReactDOM.render(
<SignIn/>,
document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Why do I receive different results when I change <form> to <div>?

There is a server made with Express.js and a signin.js form(using React) in which when you enter the right user information, you'll be directed to the home page.
The problem is that when form element is present in the following piece of code, as you enter user information, after being redirected to the home page it automatically return to the signin.js form.
When you change form element into div, everything works fine.
Plus, the request to server is made through 'Get', not as 'Post', as is specified in the code.
Here is the signin.js:
import React from 'react';
class Signin extends React.Component {
constructor(props) {
super(props);
this.state = {
signInEmail: '',
SignInPassword: ''
}
}
onEmailChange = (event) => {
this.setState({ signInEmail: event.target.value })
}
onPasswordChange = (event) => {
this.setState({ signInPassword: event.target.value })
}
onSubmitSignIn = () => {
fetch('http://localhost:3000/signin', {
method: 'post',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: this.state.signInEmail,
password: this.state.signInPassword
})
})
.then(res => res.json())
.then(data => {
if (data === 'success') {
this.props.onRouteChange('home');
}
})
}
render() {
const { onRouteChange } = this.props;
return (
<article className="br3 ba b--black-10 mv4 w-100 w-50-m w-25-l mw6 shadow-5 center">
<main className="pa4 black-80">
<div >
<fieldset id="sign_up" className="ba b--transparent ph0 mh0">
<legend className="f1 fw6 ph0 mh0">Sign In</legend>
<form className="mt3">
<label className="db fw6 lh-copy f6" htmlFor="email-address">Email</label>
<input
className="pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100"
type="email"
name="email-address"
id="email-address"
onChange={this.onEmailChange}
/>
</div>
<div className="mv3">
<label className="db fw6 lh-copy f6" htmlFor="password">Password</label>
<input
className="b pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100"
type="password"
name="password"
id="password"
onChange={this.onPasswordChange}
/>
</div>
</fieldset>
<div className="">
<input
onClick={this.onSubmitSignIn}
className="b ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib"
type="submit"
value="Sign in"
/>
</div>
<div className="lh-copy mt3">
<p onClick={() => onRouteChange('register')} className="f6 link dim black db pointer">Register</p>
</div>
</form>
</main>
</article>
);
}
}
export default Signin;
Clicking a type="submit" button in a form submits the form; that's what submit buttons are for. Submitting a form sends the form data to the form's action URL (the same page if there is none), loading the result.
If you want to send the form data via ajax instead, you should either change that to type="button" or call preventDefault on the event object.

React Plaid Component Refreshes the page

Sorry for my English, I'm not a native speaker so please don't minus me too much. I'm a beginner in programming and I'm learning from tutorials found on internet. Today is my first time asking a question on Stack Overflow. It's probably a silly question, I know there are many similar questions, but it's a different issue, it's not a duplicate. Let me move to my question.
I have a react component in which I'm using react-plaid npm package to use Plaid APi. it can be found here react-plaid
My current component code looks like this
Component
import React, {Component} from 'react';
import BuggyApi from "../../services/BuggyApi";
import BlockUi from "react-block-ui";
import ReactPlaid from 'react-plaid'
class Integration extends Component{
state={
plaid_public_key: "",
plaid_public_token: "",
blocking: false,
isSuccess: false,
errorMessage: [],
open: false,
plaidData: [],
};
componentWillMount(){
new BuggyApi().getPlaidPublicKey().then((response)=>{
console.log(response.data);
if(response.status===200){
this.setState({
plaid_public_key: response.data.public_key
});
}
}).catch((error)=>{
})
}
handleOnExit = (error, metadata)=>{
if (error != null) {
console.log('link: user exited');
console.log(error, metadata);
}
};
handleOnLoad =()=>{
console.log('link: loaded');
};
handleOnEvent =(eventname, metadata)=>{
console.log('link: user event', eventname, metadata);
};
handleOnSuccess = (public_token, metadata) => {
console.log('public_token: ' + public_token);
console.log('account ID: ' + metadata.account_id);
};
componentDidMount(){
const script = document.createElement("script");
script.src = "https://cdn.plaid.com/link/v2/stable/link-initialize.js";
script.async = true;
document.body.appendChild(script);
}
render(){
return(
<div className="page-wrapper">
<div className="content container-fluid">
<div className="row">
<div className="col-xs-8">
<h4 className="page-title">Integration</h4>
</div>
<div className="col-xs-4 text-right m-b-30">
</div>
</div>
<div className="row">
<div className="col-md-12">
<div className="text-center">
<h4 className="modal-title">
Link your bank account
</h4>
</div>
<br/>
<br/>
<form>
{(this.state.isSuccess)?
<div className="row">
<div className="col-sm-6 col-sm-offset-3">
<div className="alert alert-success">
<strong>Success!</strong> Settings updated successfully!
</div>
</div>
</div>:null
}
{(this.state.errorMessage.length>0)?
<div className="row">
<div className="col-sm-6 col-sm-offset-3">
<div className="alert alert-danger">
<ul>
{this.state.errorMessage.map((message,i) =><li key={i}>{message}</li>)}
</ul>
</div>
</div>
</div>:null
}
<BlockUi tag="div" blocking={this.state.blocking}>
<div className="row">
<div className="col-sm-6 col-sm-offset-3">
{(this.state.plaid_public_key!=="")?
<div>
<button onClick={() => this.setState({ open: true})}>Open Plaid</button>
<ReactPlaid
clientName="Arshad"
product={["auth"]}
apiKey={this.state.plaid_public_key}
env='sandbox'
open={this.state.open}
onSuccess={(token, metaData) => this.setState({plaidData: metaData})}
onExit={() => this.setState({open: false})}
/>
</div>:null
}
</div>
</div>
</BlockUi>
</form>
</div>
</div>
</div>
</div>
);
};
}
export default Integration;
The problem is when I click the open link button it just shows the Plaid model for few seconds and then refreshes the application page. I'm wondering if someone had the same and can help me out there.
Note:
Please ignore the public key state you can just set it to "c10c40c4ee5eee97764307027f74c2" in apiKey={this.state.plaid_public_key}. I'm getting the public key from the server using axious.
I think I found the issue and though it'd be OK to post my answer on stackoverflow to help others if anyone ever faces the same problem. I was putting the react-plaid-link inside the tags. The react-plaid-link returns a button which according to the html standard a button inside a form without "type" attribute acts like a submit button. Same goes here in my case which I click the the button it submit the form which causes refreshing page. I fixed the issue by just removing the tags. My updated code looks like this.
import React, {Component} from 'react';
import BuggyApi from "../../services/BuggyApi";
import BlockUi from "react-block-ui";
import ReactPlaid from 'react-plaid'
class Integration extends Component{
state={
plaid_public_key: "",
plaid_public_token: "",
blocking: false,
isSuccess: false,
errorMessage: [],
open: false,
plaidData: [],
};
componentWillMount(){
new BuggyApi().getPlaidPublicKey().then((response)=>{
console.log(response.data);
if(response.status===200){
this.setState({
plaid_public_key: response.data.public_key
});
}
}).catch((error)=>{
})
}
handleOnExit = (error, metadata)=>{
if (error != null) {
console.log('link: user exited');
console.log(error, metadata);
}
};
handleOnLoad =()=>{
console.log('link: loaded');
};
handleOnEvent =(eventname, metadata)=>{
console.log('link: user event', eventname, metadata);
};
handleOnSuccess = (public_token, metadata) => {
console.log('public_token: ' + public_token);
console.log('account ID: ' + metadata.account_id);
};
componentDidMount(){
const script = document.createElement("script");
script.src = "https://cdn.plaid.com/link/v2/stable/link-initialize.js";
script.async = true;
document.body.appendChild(script);
}
render(){
return(
<div className="page-wrapper">
<div className="content container-fluid">
<div className="row">
<div className="col-xs-8">
<h4 className="page-title">Integration</h4>
</div>
<div className="col-xs-4 text-right m-b-30">
</div>
</div>
<div className="row">
<div className="col-md-12">
<div className="text-center">
<h4 className="modal-title">
Link your bank account
</h4>
</div>
<br/>
<br/>
{(this.state.isSuccess)?
<div className="row">
<div className="col-sm-6 col-sm-offset-3">
<div className="alert alert-success">
<strong>Success!</strong> Settings updated successfully!
</div>
</div>
</div>:null
}
{(this.state.errorMessage.length>0)?
<div className="row">
<div className="col-sm-6 col-sm-offset-3">
<div className="alert alert-danger">
<ul>
{this.state.errorMessage.map((message,i) =><li key={i}>{message}</li>)}
</ul>
</div>
</div>
</div>:null
}
<BlockUi tag="div" blocking={this.state.blocking}>
<div className="row">
<div className="col-sm-6 col-sm-offset-3">
{(this.state.plaid_public_key!=="")?
<div>
<button onClick={() => this.setState({ open: true})}>Open Plaid</button>
<ReactPlaid
clientName="Arshad"
product={["auth"]}
apiKey={this.state.plaid_public_key}
env='sandbox'
open={this.state.open}
onSuccess={(token, metaData) => this.setState({plaidData: metaData})}
onExit={() => this.setState({open: false})}
/>
</div>:null
}
</div>
</div>
</BlockUi>
</div>
</div>
</div>
</div>
);
};
}
export default Integration;
Sometimes you need to put the Plaid button inside a form element, in which case, just pass (e) => e.preventDefault() in as the onClick handler
<ReactPlaid
clientName="Arshad"
product={["auth"]}
apiKey={this.state.plaid_public_key}
env='sandbox'
open={this.state.open}
onSuccess={(token, metaData) => this.setState({plaidData: metaData})}
onExit={() => this.setState({open: false})}
onClick={(e) => e.preventDefault()}
/>

Categories

Resources