React js: Stepwise Progress Bar rerendering an element - javascript

I am creating a progress bar using the package - react-step-progress-bar
My progress bar code is as below (This is just the standard code of the package)
For simplicity, i am just creating two steps
import React, { useEffect } from "react";
import "react-step-progress-bar/styles.css";
import { ProgressBar, Step } from "react-step-progress-bar";
const LoadingBar = (props) => {
console.log('Logging inside loading bar',props.progressBar)
return (
<div className="w-[50%] z-50">
<ProgressBar
percent={props.progressBar}
fillBackground="linear-gradient(to right, #fefb72, #f0bb31)"
>
<Step transition="scale">
{({ accomplished }) => (
<img
style={{ filter: `grayscale(${accomplished ? 0 : 80}%)`, transform: "" }}
width="60"
src="/loadingBar/verifiedHashFiles.png"
alt=""
/>
)}
</Step>
<Step transition="scale">
{({ accomplished }) => (
<img
style={{ filter: `grayscale(${accomplished ? 0 : 80}%)`, transform: "" }}
width="60"
src="/loadingBar/verifiedTransaction.png"
alt=""
/>
)}
</Step>
</ProgressBar>
</div>
)
}
export default LoadingBar
I am using this to create a progressive bar in the way below in my home page
import axios from 'axios';
import React, { useContext, useEffect, useState, useCallback } from 'react'
import cuid from "cuid";
import { DataContext } from '../Context/DataContext';
import { Dropzone, FileVerificationFailed, FileVerificationSuccessful } from '../Components'
import "react-step-progress-bar/styles.css";
import LoadingBar from './LoadingBar';
export function Home() {
const [progressBar, setprogressBar] = useState(0);
const sendFileToIPFS = async (e) => {
e.preventDefault();
if (fileImg) {
try {
const formData = new FormData();
formData.append("file", fileImg);
const resFile = await axios({
method: "post",
url: "https://api.pinata.cloud/pinning/pinFileToIPFS",
data: formData,
headers: {
'pinata_api_key': `${process.env.REACT_APP_PINATA_API_KEY}`,
'pinata_secret_api_key': `${process.env.REACT_APP_PINATA_API_SECRET}`,
"Content-Type": "multipart/form-data"
},
});
setprogressBar(50)
if (certificateData.find(uploadedFile => uploadedFile.CID === resFile.data.IpfsHash)) {
setQRurl(certificateData.find(uploadedFile => uploadedFile.CID === resFile.data.IpfsHash).QRurl)
console.log('Verified')
setVerified(true)
}
else {
console.log('Failed')
setVerificationFailed(true)
unpin(resFile.data.IpfsHash)
}
setprogressBar(100)
} catch (error) {
console.log("File to IPFS: ")
console.log(error)
}
}
}
return (
....
{progressBar!=0 && (<div className='absolute ml-[5%] mt-[5%] h-[60%] w-[60%] z-50'>
<div className='flex justify-center'>
<LoadingBar progressBar={progressBar} />
</div>
</div>)}
....
50% never gets set or logged but the bar gets to 100% directly and logs it
How do i execute this?
Please help

Related

Strange behaviour of reactjs

Consider the below UI.
You can see a heading, Logo Uploaded and Organisation logo
Logo Uploaded are the general logo of the application
Organisation logo is the single logo uploaded specific to the org
LogoComponent.jsx
import React, { useEffect, useState } from "react";
import { Card } from "reactstrap";
import UploadLogo from "./UploadLogo";
import axios from "axios";
import BASE_URL from "../../config/urls";
import DeleteIcon from "#material-ui/icons/Delete";
import { IconButton } from "#material-ui/core";
import { makeStyles } from "#material-ui/core/styles";
import UploadLogoOfOrg from "./UploadLogoOfOrg";
const useStyles = makeStyles((theme) => ({
DeleteIcon: {
fontSize: "15px",
color: "black",
},
}));
export default function OrgLogoCard({ orgId }) {
const classes = useStyles();
const [logos, setLogos] = useState([]);
const [orgLogo, setOrgLogo] = useState("");
useEffect(() => {
axios
.get(`${BASE_URL}client/get-logo-org?_id=${orgId}`, {
headers: {
"Content-Type": "multipart/form-data",
"x-access-token": localStorage.getItem("vyoriusUserAuth"),
},
})
.then((res) => setLogos(res.data))
.catch((err) => {
console.log(err);
});
axios
.get(`${BASE_URL}client/get-logo-of-org?_id=${orgId}`, {
headers: {
"x-access-token": localStorage.getItem("vyoriusUserAuth"),
},
})
.then((res) => setOrgLogo(res.data))
.catch((err) => {
console.log(err);
});
}, []);
const addLogo = (logo) => {
setLogos([...logos, logo]);
};
const deleteIcon = (logo) => {
axios
.post(
`${BASE_URL}client/remove-logo-org`,
{
_id: orgId,
logo,
},
{
headers: {
"x-access-token": localStorage.getItem("vyoriusUserAuth"),
},
}
)
.then((_) => {
setLogos(logos.filter((l) => l != logo));
})
.catch((err) => {
console.log(err, err?.response?.data);
alert("Can not remove logo at the moment!");
});
};
return (
<Card className="m-2 p-2 border-0">
<div className="d-flex">
<h6 className="mr-2 ml-2">Logo Uploaded</h6>{" "}
<UploadLogo orgId={orgId} addLogo={addLogo} />
</div>
<div>{logos.length == 0 && "There is no logo!"}</div>
<div className="d-flex p-2 flex-wrap">
{logos.map((ele, index) => (
<div key={index} className="position-relative">
<img
className="mr-1 mt-1"
src={ele}
alt=""
style={{
height: "40px",
width: "80px",
}}
/>
<div
style={{
top: "-10px",
right: "0px",
}}
className="position-absolute"
>
<IconButton
onClick={() => deleteIcon(ele)}
color="secondary"
aria-label="delete"
size="small"
>
<DeleteIcon className={classes.DeleteIcon} fontSize="inherit" />
</IconButton>
</div>
</div>
))}
</div>
<div className="d-flex mt-4">
<h6 className="mr-2 ml-2">Organization logo</h6>{" "}
<UploadLogoOfOrg
orgId={orgId}
addLogo={(loc) => setOrgLogo(loc)}
/>
</div>
<div className="d-flex">
<img
className="mr-1 mt-1"
src={orgLogo}
alt=""
style={{
height: "40px",
width: "80px",
}}
/>
</div>
</Card>
);
}
UploadLogo.jsx
import React from "react";
import AddAPhotoIcon from "#material-ui/icons/AddAPhoto";
import axios from "axios";
import { BASE_URL } from "../../config/urls";
import { connect } from "react-redux";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
AddAPhotoIcon: {
height: "1rem",
marginTop: "-10px",
color: "black",
},
}));
// isOrgLogo - logo of the org
function UploadOrgLogos({ userInfo, addLogo, orgId }) {
const classes = useStyles();
return (
<form>
<label
htmlFor="file-input"
style={{
cursor: "pointer",
}}
>
<AddAPhotoIcon className={classes.AddAPhotoIcon} color="primary" />
</label>
<input
style={{
display: "none",
}}
id="file-input"
type="file"
onChange={(e) => {
if (!e.target.files[0]) return;
// if there is no user
// TODO: add toast notification
if (!userInfo || !userInfo.email) {
console.log("User is not in redux!");
}
const role = userInfo.userRole.find(
(role) => role.organization == orgId
);
if (!role || role.role != "SuperAdmin") {
alert("Not a super admin!");
return;
} else {
console.log("A super admin!");
}
let formData = new FormData();
formData.append("file", e.target.files[0]);
formData.append("folder", "org-logos");
formData.append("fileId", "org-logo");
formData.append("bucket", "vyoriusdronesdatabase");
formData.append("_id", orgId);
axios
.post(`${BASE_URL}client/add-logo-org`, formData, {
headers: {
"Content-Type": "multipart/form-data",
"x-access-token": localStorage.getItem("vyoriusUserAuth"),
},
})
.then((res) => addLogo(res.data))
.catch((err) => {
console.log(err);
alert("Error in uploading file...");
});
}}
/>
</form>
);
}
const mapStateToProps = ({ login_details }) => {
return {
userInfo: login_details.login_detail,
};
};
// HMR
export default connect(mapStateToProps, null)(UploadOrgLogos);
UploadLogoOfOrg.jsx
import React from "react";
import AddAPhotoIcon from "#material-ui/icons/AddAPhoto";
import axios from "axios";
import { BASE_URL } from "../../config/urls";
import { connect } from "react-redux";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
AddAPhotoIcon: {
height: "1rem",
marginTop: "-10px",
color: "black",
},
}));
function UploadOrgLogos({ userInfo, addLogo, orgId }) {
const classes = useStyles();
return (
<form>
<label
htmlFor="file-input"
style={{
cursor: "pointer",
}}
>
<AddAPhotoIcon className={classes.AddAPhotoIcon} color="primary" />
</label>
<input
style={{
display: "none",
}}
id="file-input"
type="file"
onChange={(e) => {
if (!e.target.files[0]) return;
// if there is no user
// TODO: add toast notification
if (!userInfo || !userInfo.email) {
console.log("User is not in redux!");
}
const role = userInfo.userRole.find(
(role) => role.organization == orgId
);
if (!role || role.role != "SuperAdmin") {
alert("Not a super admin!");
return;
} else {
console.log("A super admin!");
}
let formData = new FormData();
formData.append("file", e.target.files[0]);
formData.append("folder", "org-logos");
formData.append("fileId", "org-logo");
formData.append("bucket", "vyoriusdronesdatabase");
formData.append("_id", orgId);
axios
.post(`${BASE_URL}client/add-logo-of-org`, formData, {
headers: {
"Content-Type": "multipart/form-data",
"x-access-token": localStorage.getItem("vyoriusUserAuth"),
},
})
.then((res) => addLogo(res.data))
.catch((err) => {
console.log(err);
alert("Error in uploading file...");
});
}}
/>
</form>
);
}
const mapStateToProps = ({ login_details }) => {
return {
userInfo: login_details.login_detail,
};
};
// HMR
export default connect(mapStateToProps, null)(UploadOrgLogos);
Clicking on any one of them, the request is being sent to client/add-logo-org. If I remove <UploadLogo orgId={orgId} addLogo={addLogo} / from LogoComponent.jsx then its working fine.
Edited
If I swap <UploadLogoOfOrg orgId={orgId} addLogo={(loc) => setOrgLogo(loc)} /> with <UploadLogo orgId={orgId} addLogo={addLogo} /> then all request are being sent on /client/add-logo-of-org.
My own ans
The problem is resolved, in both component <input id="file-input">, this file-input is was causing the issue. I changed it in one component from file-input to file-input-1 and it worked fine.
#SayyedDawood

ReactJS, Swiper slider with axios

I have a Swiper slider on a react website, when I take the data from a local json file everything works fine. I had to take the data from public foler so I used axios but I can't scroll anymore in the slider. I think it's a conflict between the Axios and the Swiper plugin but I have no idea how to solve it.
Thanks! :)
Here is the code from the page:
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import Loader from "../container/Loader";
import { Helmet } from "react-helmet";
import { Col } from "react-bootstrap";
import Cookies from "../components/cookies";
import LayoutDefault from "../container/LayoutDefault";
import HeaderProject from "../components/header/HeaderProject";
import ImageSlider from "../container/ImageSlider";
const ProjectPage = ({ match }) => {
const { params: { projectId } } = match;
const [projects, setProjects] = useState(null)
useEffect(() => {
var isCancelled = false;
axios.get("./projects.json").then(
(response) => !isCancelled ? setProjects(response.data) : console.log("is canceled")
).catch(
(err) => console.log(err)
)
}, [])
const goToPreviousPage = () => {
if (window.history.length === 1) {
window.location = "/"
} else {
window.history.back();
}
}
return (
<Loader>
<Helmet>
<title>TheBrandBar | {projects ? projects[projectId - 1].title : ""}</title>
</Helmet>
<Cookies />
<LayoutDefault className="template-color-2 bg_color--4 project-page">
<button onClick={goToPreviousPage} className="page-close" />
<Col>
<HeaderProject
title={projects ? projects[projectId - 1].title : ""}
description={projects ? projects[projectId - 1].description : ""}
/>
</Col>
<ImageSlider
index={projectId}
projects = {projects}
/>
</LayoutDefault>
</Loader>
);
};
export default ProjectPage;
and imageSlider component
import React, { useState } from 'react';
import { Col } from "react-bootstrap";
import SliderSwiper from "../components/swiper";
const ImageSlider = ({ index, projects }) => {
const [swiper, updateSwiper] = useState(null);
const settings = {
slidesPerView: "auto",
spaceBetween: 0,
autoplay: false,
mousewheel: true,
loop: false,
freeMode: true,
};
const goNext = () => {
if (swiper !== null) {
swiper.slideNext();
}
};
// const goPrev = () => {
// if (swiper !== null) {
// swiper.slidePrev();
// }
// };
return (
<div className="pt--10 pb-10">
<SliderSwiper
reference={updateSwiper}
settings={settings}
>
{
projects ? projects[index - 1].images.map((image) => (
<div key={image} className="image-slide mt--15">
<img src={`${process.env.PUBLIC_URL}/projects/${index}/${image}`} alt="" />
</div>
)) : ""
}
</SliderSwiper>
{/* <button onClick={goPrev} className="swipper-btn swiper-btn-prev">
<i className="fa fa-angle-left" />
</button> */}
<Col>
<div onClick={goNext} className="scroll-btn mt--25">
<span>SCROLL TO SEE MORE</span>
<span className="btn-arrow" />
</div>
</Col>
</div>
);
};
export default ImageSlider;

Need help for React code fetch request delete operation

I am able to post and get data but unable to delete must be a problem with an id that I am passing to the delete note function.
these are my files:
Note.js
import React, {useState} from 'react';
import DeleteIcon from '#material-ui/icons/Delete';
import EditIcon from '#material-ui/icons/Edit';
import SaveIcon from '#material-ui/icons/Save';
function Note(props) {
function handleClick() {
props.onDelete(props.id);
}
const[edit, setEdit]=useState(false);
function editTrue() {
setEdit(!edit);
}
return(
<div className={!edit ? "note" : "note1"}>
<h1 contentEditable={edit && "true"} spellCheck="true">{props.title}</h1>
<hr/>
<p />
<p contentEditable={edit && "true"} spellCheck="true">{props.content}</p>
{!edit && <button onClick={handleClick}><DeleteIcon /></button>}
{edit ? <button onClick={editTrue}> <SaveIcon /> </button> : <button onClick={editTrue}><EditIcon /></button>}
</div>
);
}
export default Note;
App.js
import React, { useState, useEffect } from 'react';
//import { DragDropContext } from 'react-beautiful-dnd';
import Header from './Header';
import Footer from './Footer';
import Note from './Note';
import CreateArea from './CreateArea'
function App() {
const [notes, setNotes] = useState([]);
useEffect(() => {
fetch('https://react-hooks-update-ec587-default-rtdb.firebaseio.com/notes.json')
.then(response => response.json())
.then(responseData => {
const loadedNotes = [];
for( const key in responseData ) {
loadedNotes.push({
id: key,
title: responseData[key].title,
content: responseData[key].content
});
}
setNotes(loadedNotes);
});
}, []);
function addNote(newNote) {
fetch('https://react-hooks-update-ec587-default-rtdb.firebaseio.com/notes.json', {
method: 'POST',
body: JSON.stringify(newNote),
headers: { 'content-Type': 'application/json' }
}).then(response => {
return response.json();
}).then(responseData => {
setNotes(prevNotes => [
...prevNotes,
{ id: responseData.name, ...newNote }
]);
});
}
function deleteNote(noteId) {
fetch(`https://react-hooks-update-ec587-default-rtdb.firebaseio.com/notes/${noteId}.json`,
{
method: 'DELETE'
}
).then(response => {
setNotes(prevNotes => {
return prevNotes.filter((noteItem, index) => {
return index !== noteId;
});
});
});
}
return(
<div>
<Header />
<CreateArea
onAdd={addNote}
/>
{notes.map((noteItem, index) => {
return (
<Note
key={index}
id={index}
title={noteItem.title}
content={noteItem.content}
onDelete={deleteNote}
/>
);
})}
<Footer />
</div>
);
}
export default App;
what changes I can do?
when I run my file delete operation is working locally but it does not delete the note from the database
I am able to post and get data but unable to delete must be a problem with an id that I am passing to the delete note function.
May be in deleteNote in fetch url remove .json:
fetch(`https://react-hooks-update-ec587-default-rtdb.firebaseio.com/notes/${noteId}`)

How to open another tab using React

I have written a simple piece of code to open another tab using React. It currently does not work. I think that something very simple has gone wrong but I am unsure where.
Message.component.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import { fetchData, GET } from '../DAL';
import Inbox from "/Messages/GetMessages";
<Route path="/Messages/GetMessages" component={MENU.inbox} />
handleClick()
{
//this will open the inbox in a new tab
window.open("/Messages/GetMessages");
}
I have added the reference in the Dal.js file
Dal.js
export function fetchData(API)
{
return getAsync(API);
}
async function getAsync(API)
{
try
{
let response = await fetch(API);
let data = await response.json();
data = JSON.parse(data);
return data;
}
catch (e)
{
console.log("ERROR FOUND IN " + API, e);
return [];
}
}
export const GET = {
INBOX:'Messages/GetMessages'}
It is also in the menu component, so that it can be seen where it is used.
Menu.component.jsx
import React from 'react';
import { Button, Icon } from 'semantic-ui-react'
export const MENU = {
INBOX: 'INBOX'
};
export default class MainMenu extends React.Component {
constructor(props)
{
super(props)
this.state = {
active: MENU.ASSETS
};
}
_onClick = (item) =>
{
if (this.state.active !== item)
{
this.setState({active: item})
}
() => this.props.visible();
}
_triggerUserProfile()
{
showEditUserForm(51, 10)
}
render() {
let buttonStyle = {backgroundColor: '#5d7090', color: 'white'};
let icon = this.props.icon;
return (
<MainMenuContainer>
<div style={{margin: '5px'}}>
<img width='75px' style={{marginBottom: '5px'}} src="Content/img/logo_white.svg"/>
<IconButton onClick={() => this.props.visible()}>
<Icon name={icon}></Icon>
</IconButton>
<span onClick={() => this._triggerUserProfile()} style={{float: 'right', color: 'white', marginBottom: 'auto', marginTop:'7px', cursor: 'pointer'}}>Welcome Back, Alex! <Icon name='chevron down'></Icon></span>
</div>
<div>
<Button animated='vertical' style={buttonStyle} onClick={() =>
this.props.handleClick(MENU.INBOX)}>
<Button.Content hidden>Inbox</Button.Content>
<Button.Content visible>
<Icon name='mail' />
</Button.Content>
</Button>
</div>
</MainMenuContainer>
Currently nothing happens and the react crashes silently.
You can try like this : window.open("url","_self");
You're looking for
window.open('url', '_blank');

How to pass my onSucceeded() function to the parent component?

I have 2 components OptinPage (parent) and TermsOfServices (child). Optin Page is only used for rendering the TermsOfServices component, which can be reused elsewhere in the application. I want to use my onSucceeded () function from my child component to my parent component. I don't see how to do it at all. Currently the result is such that when I click on the button that validates the TermsOfServices it seems to be an infinite loop, it goes on and on without closing my popup. Before I split my TermsOfServices component into a reusable component it worked fine. Before, all content was gathered in OptinPage. Any ideas? Thanks in advance
my TermsOfServices component:
import API from 'api';
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import {
Block,
BlockTitle,
Col,
Fab,
Icon,
Preloader,
} from 'framework7-react';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-refetch';
import ReactHtmlParser from 'react-html-parser';
class TermsOfServices extends PureComponent {
static propTypes = {
agreeTosFunc: PropTypes.func.isRequired,
agreeTos: PropTypes.object,
onSucceeded: PropTypes.func,
tos: PropTypes.object.isRequired,
};
static contextTypes = {
apiURL: PropTypes.string,
loginToken: PropTypes.string,
userId: PropTypes.string,
};
static defaultProps = {
agreeTos: {},
onSucceeded: () => {},
};
state = {
currentTos: -1,
};
componentDidUpdate(prevProps) {
const {
agreeTos,
onSucceeded,
tos,
} = this.props;
const { currentTos } = this.state;
/* Prepare for first tos after receiving all of them */
if (
prevProps.tos.pending &&
tos.fulfilled &&
tos.value.length &&
currentTos < 0
) {
this.setState({ currentTos: 0 });
}
/* When sending ToS agreement is done */
if (
prevProps.agreeTos.pending &&
agreeTos.fulfilled
) {
onSucceeded();
}
}
handleNext = () => {
const { agreeTosFunc, tos } = this.props;
const { currentTos: currentTosId } = this.state;
const termsOfServices = tos.value;
const done = currentTosId + 1 === termsOfServices.length;
this.setState({ currentTos: currentTosId + 1 });
if (done) {
agreeTosFunc(termsOfServices.map((v) => v._id));
}
};
render() {
const { tos } = this.props;
const { currentTos: currentTosId } = this.state;
const termsOfServices = tos.value;
const currentTermsOfServices = termsOfServices && termsOfServices[currentTosId];
const loaded = termsOfServices && !tos.pending && tos.fulfilled;
const htmlTransformCallback = (node) => {
if (node.type === 'tag' && node.name === 'a') {
// eslint-disable-next-line no-param-reassign
node.attribs.class = 'external';
}
return undefined;
};
return (
<div>
{ (!loaded || !currentTermsOfServices) && (
<div id="
optin_page_content" className="text-align-center">
<Block className="row align-items-stretch text-align-center">
<Col><Preloader size={50} /></Col>
</Block>
</div>
)}
{ loaded && currentTermsOfServices && (
<div id="optin_page_content" className="text-align-center">
<h1>
<FormattedMessage id="press_yui_tos_subtitle" values={{ from: currentTosId + 1, to: termsOfServices.length }} />
</h1>
<BlockTitle>
{ReactHtmlParser(
currentTermsOfServices.title,
{ transform: htmlTransformCallback },
)}
</BlockTitle>
<Block strong inset>
<div className="tos_content">
{ReactHtmlParser(
currentTermsOfServices.html,
{ transform: htmlTransformCallback },
)}
</div>
</Block>
<Fab position="right-bottom" slot="fixed" color="pink" onClick={() => this.handleNext()}>
{currentTosId + 1 === termsOfServices.length &&
<Icon ios="f7:check" aurora="f7:check" md="material:check" />}
{currentTosId !== termsOfServices.length &&
<Icon ios="f7:chevron_right" aurora="f7:chevron_right" md="material:chevron_right" />}
</Fab>
{currentTosId > 0 && (
<Fab position="left-bottom" slot="fixed" color="pink" onClick={() => this.setState({ currentTos: currentTosId - 1 })}>
<Icon ios="f7:chevron_left" aurora="f7:chevron_left" md="material:chevron_left" />
</Fab>
)}
</div>
)}
</div>
);
}
}
export default connect.defaults(new API())((props, context) => {
const { apiURL, userId } = context;
return {
tos: {
url: new URL(`${apiURL}/tos?outdated=false&required=true`),
},
agreeTosFunc: (tos) => ({
agreeTos: {
body: JSON.stringify({ optIn: tos }),
context,
force: true,
method: 'PUT',
url: new URL(`${apiURL}/users/${userId}/optin`),
},
}),
};
})(TermsOfServices);
My OptIn Page :
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import {
Link,
NavRight,
Navbar,
Page,
Popup,
} from 'framework7-react';
import { FormattedMessage, intlShape } from 'react-intl';
import './OptInPage.scss';
import TermsOfServices from '../components/TermsOfServices';
class OptinPage extends PureComponent {
static propTypes = {
logout: PropTypes.func.isRequired,
opened: PropTypes.bool.isRequired,
};
static contextTypes = {
intl: intlShape,
logout: PropTypes.func,
};
render() {
const { opened, logout } = this.props;
const { intl } = this.context;
const { formatMessage } = intl;
return (
<Popup opened={opened} className="demo-popup-swipe" tabletFullscreen>
<Page id="optin_page">
<Navbar title={formatMessage({ id: 'press_yui_tos_title' })}>
<NavRight>
<Link onClick={() => logout()}>
<FormattedMessage id="press_yui_comments_popup_edit_close" />
</Link>
</NavRight>
</Navbar>
</Page>
<TermsOfServices onSucceeded={this.onSuceeded} />
</Popup>
);
}
}
export default OptinPage;
Just add the data you want the parent to be supplied with in the child component (when it is hit) and then handle the data passed to the parent in the function that you pass in onSuccess.
This will roughly look like this:
const {useState, useEffect} = React;
function App(){
return <Child onSuccess={(data)=>{console.log(data)}}/>;
}
function Child({onSuccess}){
return <div>
<button
onClick={()=>onSuccess("this is the data from the child component")}>
Click to pass data to parent
</button>
</div>;
}
ReactDOM.render(<App/>,document.getElementById('app'));
#element {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id='app'></div>
<div id="element">
<div>node 1</div>
<div>node 2</div>
</div>
to access to parent method or attribute you should use super,
for call to the parent constructor
super([arguments]);
for call parent method
super.parentMethod(arguments);
I recommend create a method on child class and then call the parent method, not directly
for more information take a look on this
https://www.w3schools.com/jsref/jsref_class_super.asp

Categories