Edit CSS of React Components - javascript

I am using a react component react-awesome-modal as follows.
<Modal visible={this.state.visible} width="850" height="450" effect="fadeInUp" onClickAway={() => this.closeModal()}>
Now I want to add a new style overflow-y:scroll to this Modal component.
I tried doing this, but it didn't worked:
<Modal visible={this.state.visible} style={{"overflow-y":"scroll"}} width="850" height="450" effect="fadeInUp" onClickAway={() => this.closeModal()}>
Is there any way I can apply the property to this component.
PS: I had tried applying this property using chrome Devtool(Inspect element). In that, I am able to see the complete CSS that is used for this component, so I was able to update it easily (see the last line in the image)

You could try insert a div element under <Modal /> , then set the style of this div:
<Modal visible={this.state.visible} width="400" height="300" effect="fadeInUp" onClickAway={() => this.closeModal()}>
<div style={{overflowY:"scroll", height:"300px"}}>
<h1>Title</h1>
<p>Some Contents</p>
<a href="javascript:void(0);" onClick={() => this.closeModal()}>Close</a>
</div>
</Modal>
If solution above doesn't work, then try creatRef, get DOM of <Modal />, and change the style of <Modal />: (React version must be newer than 16.3)
import React, { Component } from 'react';
import Modal from 'react-awesome-modal';
class Test extends React.Component {
constructor(props) {
super(props)
this.modalRef = React.createRef() //create Ref to get DOM
}
componentDidMount(){
this.modalRef.current.style.overflowY = "scroll" //change style of Modal DOM
}
render() {
return (
<div>
<Modal visible={this.state.visible} width="400" height="300" effect="fadeInUp" onClickAway={() => this.closeModal()} ref={this.modalRef}>
<div>
<h1>Title</h1>
<p>Some Contents</p>
<a href="javascript:void(0);" onClick={() => this.closeModal()}>Close</a>
</div>
</Modal>
</div>
)
}
}

Related

NextJS: Reload iFrame from another component

I have a NextJS application, with the following page:
Page:
import Layout from "#/components/app/Layout";
import Sidebar from "#/components/app/Sidebar";
export default function SiteIndex() {
return (
<Layout>
<div className="flex">
<Sidebar />
<div className="m-5">
<iframe src="/page.htm"></iframe>
</div>
</div>
</Layout>
);
}
This page has an iframe, a parent Layout component, and one more component called Sidebar.
Parent Layout:
export default function Layout({ children }) {
return (
<div>
<div class="h-12 bg-gray-200 flex">
<div className="m-2 grow">Parent Layout</div>
<button className="bg-blue-500 text-white p-3">Reload iFrame Button</button>
</div>
<div>{children}</div>
</div>
)
}
Sidebar:
export default function Sidebar() {
return (
<div className="w-64 border border-r-100 m-5">
<div>Sidebar</div>
<button className="bg-blue-500 text-white p-3">Reload iFrame Button</button>
</div>
)
}
Both Layout and Sidebar have a button. I want to be able to reload the iframe on the press of any of those buttons. How can I achieve this in react/nextjs project? primarily I'm looking for the best way to reload an iFrame within reactjs.
Would it work for your application to add a key={keyValue} to the iframe? You can then set the value of that key whenever the button gets pressed. This should cause a re-render.
export default function SiteIndex() {
const [keyValue, setKeyValue] = useState(0);
return (
<Layout onButtonClick={() => setKeyValue(keyValue + 1)} >
<div className="flex">
<Sidebar onButtonClick={() => setKeyValue(keyValue + 1)} />
<div className="m-5">
<iframe src="/page.htm" key={keyValue}></iframe>
</div>
</div>
</Layout>
);
}
And in your component

react error: "TypeError: Cannot read properties of undefined (reading 'props')"

I am trying to make a popUp for each of my gallery items containing some information on the picture. Clicking on the picture and showing the pop up works fine, but I can't close it. I get the error that can be read in the title. I understand that there probably is an error regarding the sending of the "setButtonPopUp", but I couldn't understand it yet.
PopUp.js
import React from "react";
import "./PopUp.css";
export default function PopUp(props) {
return props.trigger ? (
<div className="popUpWrapper">
<div className="popUp">
<button
className="closePopUp"
onClick={onClick={props.setTrigger}}
>
close
</button>
{props.children}
</div>
</div>
) : (
""
);
}
GalleryItem.js
import "./GalleryItem.css";
import TextItem from "../TextItem/TextItem.js";
import AlertMessage from "../alertMessage.js";
import PopUp from "../PopUp/PopUp.js";
import { useState } from "react";
export default function GalleryItem({ itemData }) {
const [buttonPopUp, setButtonPopUp] = useState(false);
if (itemData.polaroid === "light") {
return (
<div
className="itemContainer"
onClick={() => setButtonPopUp(true)}
>
<PopUp trigger={buttonPopUp} setTrigger={() => {
setButtonPopUp(false);
}}>
<h3>Info</h3>
<p>{itemData.info}</p>
</PopUp>
<img className="clip" src="../../assets/klammer.png" alt="" />
<img className="polaroid" src="../../assets/polaroid.png" alt="" />
<img className="image" src={itemData.src} alt="" />
<h2 className="polaroidTitleLight">{itemData.title}</h2>
</div>
);
} else if (itemData.polaroid === "dark") {
return (
<div
className="itemContainer"
onClick={() => AlertMessage(itemData.info)}
>
<img className="clip" src="../../assets/klammer.png" alt="" />
<img className="polaroid" src="../../assets/polaroid_dark.png" alt="" />
<img className="image" src={itemData.src} alt="" />
<h2 className="polaroidTitleDark">{itemData.title}</h2>
</div>
);
} else {
return <TextItem itemData={itemData} />;
}
}
What I did notice is that if I try to use the PopUp Component directly in App.js, the PopUp works just fine. But If I try to use it in SiteChanger it's not working anymore. This is the App.js:
App.js
import "./App.css";
import Header from "../Header/Header.js";
import SiteChanger from "../changeSite/changeSite.js";
function App() {
return (
<div>
<Header />
<SiteChanger />
</div>
);
}
export default App;
All help would be greatly appreciated!
You're not sending the prop setTrigger here:
<div
className="itemContainer"
onClick={() => setButtonPopUp(true)}
setTrigger={setButtonPopUp} // Should go to down PopUp
>
<PopUp trigger={buttonPopUp}>
<h3>Info</h3>
<p>{itemData.info}</p>
</PopUp>
Also, there's no this in functional components. It's just props. Here's the solution:
<button
className="closePopUp"
onClick={() => props.setTrigger(false)}
//---------------^^^^^ // Update this
>
Send the props to correct component and not <div>:
<div
className="itemContainer"
onClick={() => setButtonPopUp(true)}
// setTrigger={setButtonPopUp} // Remove this and...
>
<PopUp trigger={buttonPopUp} setTrigger={setButtonPopUp}> // Add here.
<h3>Info</h3>
<p>{itemData.info}</p>
</PopUp>

React pass ref throw functional components in different levels

I would like to scroll to menu element in a page.
I have the menu component which is not a parent of components to which I would like to scroll.
I have found this post that describe a similar problem
Passing ref to a child We want the ref to be attached to a dom element, not to a react component. So when passing it to a child
component we can't name the prop ref.
const myRef = useRef(null)
return <ChildComp refProp={myRef}></ChildComp> } ```
Then attach the ref prop to a dom element. ```jsx const ChildComp =
(props) => {
return <div ref={props.refProp} /> } ```
Here's my app structure
Menu component:
const MenuApp = () => {
return (
<div>
<div className="desktop-menu">
<div className="menu-item a-propos">
<p className='button'>Me découvrir</p>
</div>
<div className="menu-item competences">
<p className='button'>Compétences </p>
</div>
<div className="menu-item experiences">
<p className='button'>Experiences</p>
</div>
<div className="menu-item formation">
<p className='button'>Formation </p>
</div>
</div>
</div>
)
}
The parent is app component
<div className="App">
<div className="hero">
<HeaderApp />
<ApprochApp />
</div>
<Apropos />
<Competences />
<Experiences />
<Formation />
<Recom />
<Contact />
<Footer />
</div >
I would like that mu menus scrolls to the react components in the main App component
So how can I passe the reference from the menu component to the app and use it in components to scroll ?
I do not understand your problem completely though. However, one thing I can see from your question is that you're not forwarding the ref properly.
What you need in this case is forwardRef.
Basically, what you need to do is to create the childComponent as something like this:
const childComponent = React.forwardRef(({...otherProps}, ref) => {
return (<><div ref={ref}>Component content </div></>)
})
Where you need to use the component all you need to do is this:
const parentComponent = () => {
const reveiwsRef = React.useRef("");
return (
<div>
<childComponent ref={reviewsRef} />
</div>
);
}
You can find more info about this on the react documentation: Forwarding-Refs
I have hope this helps though

How to change Modal state from outside the React class?

I am trying to call my modal by changing the state from outside the react class. But so far no luck. I tried the following:
I have a method named Portfolio which needs to activate the modal once user click on the Image
const Portfolio = (props) =>
<div className="col-sm-4">
<div className="mb-2">
<img
onClick={this.toggle}
className="card-img-top"
src={"/assets/imgs/project/"+props.portfolio.img_thumb}
alt="" />
</div>
</div>
Here is the Class that contain the state and the modal. But I cannot change state to activate the modal.
class Project extends React.Component
{
constructor(props, context) {
super(props, context);
this.state = {
modal: false,
}
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState({
modal: !this.state.modal
});
}
render(){
return (
<div className="row portfolioWrap">
// here resides our modal which activate once modal state changed
<div>
<Modal
isOpen={this.state.modal}
toggle={this.toggle}
className={this.props.className}>
<ModalHeader toggle={this.toggle}>Modal title</ModalHeader>
<ModalBody>
{this.state.gallery.map(gallery =>
<img
className="card-img-top"
src={"/assets/imgs/project/"+gallery} alt="" />)
}
</ModalBody>
<ModalFooter></ModalFooter>
</Modal>
</div>
// calling portfolio method inside the loop
{currentTodos.map(item => <Portfolio key={item.title} portfolio={item} />)}
</div>
)
}
}
I am trying to activate the modal from Portfolio function. But since its outside the class scope i cannot access the state. Is there any way to accomplish this?
You can pass the toggle method to your Portfolio component then use it from the props.
<Portfolio key={item.title} toggle={this.toggle} portfolio={item} />
Then in Portfolio:
const Portfolio = (props) =>
<div className="col-sm-4">
<div className="mb-2">
<img
onClick={props.toggle}
className="card-img-top"
src={"/assets/imgs/project/"+props.portfolio.img_thumb}
alt="" />
</div>
</div>

Handling the a onClick event in React

I'm using the following component to display a list of images in React.
class Viewer extends React.Component{
constructor(props){
super(props);
this.state = {
images : ImageList
};
}
render(){
return (
<div className="row">
<div className="image-viewer">
<ul className="list-inline">
{this.state.images.map(function (image) {
return (<li key={image.mediaId}><a href="#"><img src={image.src}
className="img-responsive img-rounded img-thumbnail"
alt={image.mediaId}/></a></li>);
})}
</ul>
</div>
</div>
);
}
}
I want to trap the onClick event on an image to do some processing, like apply a CSS to put an overlay. How do I do this in React. Please understand I'm rank new to React.
If you update your component to have onClick={this.onImageClick.bind(this, image.mediaId) you can then handle the onClick plus know which image it was that was clicked, save that on state, and use it to apply a className to the image on render (if that's what it is that you want!).
So something like this:
{this.state.images.map(function (image) {
return (<li key={image.mediaId} className={this.state.activeImage === image.mediaId ? 'active' : undefined}><a href="#" onClick={this.onClick.bind(this, image.mediaId)}><img src={image.src} className="img-responsive img-rounded img-thumbnail" alt={image.mediaId}/></a></li>);
})}
And then onClick handler -
onClick: function (mediaId) {
this.setState({activeImage: mediaId});
}

Categories

Resources