How to reference from iframe to web service with react.js - reactjs

We have to add eventListener from iframe to real service(button)
i can handle only iframe(react.js) and we cannot handle both of service due to cross-domain issue.
So i just tried with createRef in react.js but i can't reference outside of iframe.
import { createRef, useEffect } from "react";
const App = props => {
const selectChildReference = createRef();
useEffect(() => {
// This thing will be undefined
console.log(
selectChildReference?.current?.ownerDocument?.defaultView?.document?.getElementsByClassName(
"OgETmrvExa"
)
);
}, [selectChildReference]);
return (
<div ref={selectChildReference} className="parent">
<div className="app__main">
<h3>React Project</h3>
</div>
</div>
);
};
export default App;

Try the useRef hook instead of the createRef and add your listener methods onto the selectChildReference.current.

Related

Button don't passing data to another component. React

I have a component which is a button. Then in another component i am looping trough concerts and using this button to redirect to booking page but after clicking my data is not passed.
This is my button component:
import React from "react";
export const BookBtn = (props) => {
return (
<div>
<button
className="bookBtn"
style={{ backgroundColor: props.color }}
// onClick={props.func}
>
{props.text}
</button>
</div>
);
};
BookBtn.defaultProps = {
text: "Unavailable",
};
export default BookBtn;
Here is the button in my main component where I try to click
<a href={"/concert/" + concert.id} data={concert}>
<BookBtn text="Book a ticket" />
</a>
Here is my component where i try to redirect to and retrive my data.
import React from "react";
import { useEffect, useState } from "react";
import axios from "axios";
export const Book = (data) => {
const [concerts, setConcerts] = useState([]);
const [tickets, setTickets] = useState([]);
useEffect(() => {
const loadConcerts = async () => {
const resConcerts = await axios.get("data/concerts");
const tickets = await axios.get("/data/tickets");
};
});
return (
<div>
Booking page
<h1>{data.name}</h1>
</div>
);
};
UPDATE:
I wrapped my button in anchor tag and now i am able to redirect but still can't pass data.
Final Update
Allright, i managed to pass my data using useLocation hook.
Problem is solved.
I'd suggest using react-router to do the redirection or routing instead of anchor tags as they cause a refresh.
Use the Link tag from react-router and pass the concert state along with it!
Have a look at this https://reactrouter.com/en/main/components/link.

How to correct React Portal error: Target container is not a DOM element

im having an issue getting react portals working. I dont understand why I am receiving error message portal id is not DOM element that is clearly a valid DOM element.
I have a sandbox here
Code in its entirety presented here. The console.log reports correctly that the element is a DOM element but React is throwing an error.
import "./styles.css";
import { createPortal } from "react-dom";
import { useEffect, useState } from "react";
export default function App() {
const [portalDiv, setPortalDiv] = useState(undefined);
useEffect(() => {
let pd = document.getElementById("portalDiv");
console.log(pd);
setPortalDiv(pd);
}, []);
return (
<>
<div id="portalDiv">portal container</div>
<div className="app">
{/* {console.log("render portaldiv", portalDiv)} */}
{
(portalDiv &&
createPortal(
<>
<h1>Inside portal</h1>
</>
),
portalDiv)
}
<h1>Outside portal</h1>
</div>
</>
);
}
Any advice appreciated. Thanks.
This usecase is not recommended as stated in my comment, but here is a reproducible example.
If you intend to inject a React Node into VDOM, you should use React API for that, so you won't get a race condition while querying the DOM via DOM API.
import "./styles.css";
import { createPortal } from "react-dom";
import { useRef } from "react";
export default function App() {
const containerRef = useRef();
return (
<>
<div ref={containerRef}>portal container</div>
<div id="app">
{containerRef.current &&
createPortal(<h1>Example Element</h1>, containerRef.current)}
<h1>Outside portal</h1>
</div>
</>
);
}

why is my component getting rendered once but then failing on refresh

i am working on small react assignment,
following is my component code. So my component is getting rendered once but then it just fails.i'll attach the screenshots too, can some one please explain what is happening?is there an error in the code or is it because of some rate limiting in API i am using?
import React from 'react'
const Menu = ({events}) => {
console.log(events);
return (
<div>
{events.map((event)=>{
return( <div key={event.category}>
<h3>{event.category}</h3>
</div>)
})}
</div>
)
}
export default Menu
code working image
error on same code pic
parent component code
import React,{useState,useEffect} from 'react';
import './App.css';
import Menu from './components/Menu';
function App() {
const [isLoading,setISLoading] = useState(true);
const[events,setEvents] = useState()
const getEvents = async()=>{
const response = await fetch('https://allevents.s3.amazonaws.com/tests/categories.json');
const eventsData =await response.json()
setISLoading(false);
setEvents(eventsData);
}
useEffect(()=>getEvents(),[]);
return (
isLoading?<h1>Loading...</h1>:<Menu events = {events}/>
);
}
export default App;
May be the parent component of Menu which is supplying events is not using any loading state. So when the component is mounted and starts making ajax calls, events is undefined. You need to put a condition over there like this:
import React from 'react'
const Menu = ({events}) => {
console.log(events);
return events ? (
<div>
{events.map((event)=>{
return( <div key={event.category}>
<h3>{event.category}</h3>
</div>)
})}
</div>
) : null
}
export default Menu

ReferenceError: Component is not defined

import React from 'react';
import axios from 'axios';
class App extends React.Component {
state = { advice: '' };
componentDidMount() {
this.fetchAdvice();
}
fetchAdvice = () => {
axios.get('https://api.adviceslip.com/advice')
.then((response) => {
const { advice } = response.data.slip;
this.setState({advice});
})
.catch((error) => {
console.log(error);
})
}
render () {
const { advice } = this.state;
return (
<div className="app">
<div className="card">
<h1 className="heading">{advice}</h1>
<button className="button" onClick={this.fetchAdvice}>
<span>Give Me Advice!</span>
</button>
</div>
</div>
);
}
}
export default App;
According to your comment, you are calling App with
<li> <Link href="#advice"> <NavLink onClick={App}>Get an Advice</NavLink> </Link> </li>
The way that you are calling App is wrong. This binds the App as a function to the event onClick. This is not the way to use a React Class Component or React Router Link.
Provide a to parameter value and map it to App in the Route using the Switch statement.
For reference, checkout this example
https://reactrouter.com/web/example/basic
You can't assign a react component to an onClick event. Or i should say to any events. You can't call components like callback functions. That's wrong. React does not support routing with URL change by itself. You should use a third party library called react-router-dom. Here's a link to get you started with react router. https://reactrouter.com/web/guides/quick-start

Syncrohize react conditional rendering and typescript

In this component I trigger post loading using postsActions.getPost('1') and put it into the redux store. useSelector catches it and triggers PostPage rerender, now with header and button with onClickUse function attached that uses post.header along with the post object that it uses:
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { postsActions } from '../../store/Posts';
import styles from './PostPage.module.scss';
const PostPage = () => {
const dispatch = useDispatch();
const post = useSelector((state) => state.post);
const onClickUse = () => {
console.log(`See? I am used only when post is rendered`);
console.log(`So it's fine if I use it here: ${post.header}`);
}
useEffect(() => {
dispatch(postsActions.getPost('1'));
}, []);
return (
<div className={styles.container}>
{
post &&
<div>
<h1>{post.header}</h1>
<button onClick={onClickUse}>Click me</button>
</div>
}
</div>
);
};
export default PostPage;
The problem is that typescript yells inside onClickUse at me that post can be undefined. How do I then synchronize React conditional rendering functionality and typescript without hacks from this question, like !, as etc.
You can inline
<div className={styles.container}>
{
post &&
<div>
<h1>{post.header}</h1>
<button onClick={() => {
console.log(`See? I am used only when post is rendered`);
console.log(`So it's fine if I use it here: ${post.header}`);
}}>Click me</button>
</div>
}
</div>
or if you don't want inline functions in render, you should create a component with not falsy post in props and conditionally render it.
Typescript (in handler) knows nothing about render logic in your example

Resources