I'm new to react and thus the question,
I'm rendering a react-bootstrap Modal during form validation.
import React from 'react';
import {useState} from "react";
import {Button, Modal} from "react-bootstrap";
const CustomModal = (props) =>{
return (
<div>
<Modal show={true} animation={false}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>{props.message}</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={...}}>
Close
</Button>
</Modal.Footer>
</Modal>
</div>
)
};
export default CustomModal;
How do I implement the onClick on the Buttonto close this Modal
You can modify your code as given below.
import React from 'react';
import {useState} from "react";
import {Button, Modal} from "react-bootstrap";
const CustomModal = (props) =>{
const [isModalOpen, setModal] = useState(true); // You can pass default state (true/false) from props as parameter into useState. i.e. useState(props.isModalOpen)
return (
<div>
<Modal show={isModalOpen} animation={false}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>{props.message}</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={() => setModal(false)} >
Close
</Button>
</Modal.Footer>
</Modal>
</div>
)
};
export default CustomModal;
Add onHide={ () => setModal(false)} to <Modal... > for using closeButton
and for Button add setModal(false) to onClick.
const CustomModal = (props) =>{
const [isModalOpen, setModal] = useState(true); // You can pass default state (true/false) from props as parameter into useState. i.e. useState(props.isModalOpen)
return (
<div >
<Modal show={isModalOpen} onHide={ () => setModal(false)} animation={false}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>{props.message}</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={() => setModal(false)} >
Close1
</Button>
</Modal.Footer>
</Modal>
</div>
)
};
for more code efficiency you can extract () => setModal(false) and put in function.
like handleClose() { setModal(false); }
const CustomModal = (props) =>{
const [isModalOpen, setModal] = useState(true); // You can pass default state (true/false) from props as parameter into useState. i.e. useState(props.isModalOpen)
const handleClose=({isOpen})=> { setModal(isOpen);//Do somthings els for example remove temporary variables
}
return (
<div >
<Modal show={isModalOpen} onHide={ () => handleClose(false)} animation={false}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>{props.message}</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={() => handleClose(false)} >
Close1
</Button>
</Modal.Footer>
</Modal>
</div>
)
};
Currently you have a hard-coded value for show={true}. Instead, use a variable with the value of True. Then using a function with onClick, you can set the variable to false in order to close the modal.
e.g. show={isOpen}
Related
I have a modal that I want to open in useffect here is the my code in carvin function console.log working but modal didn't popup. I have made one main component as Loyaltycash and calling carvin in useeffect
import React, { useState, useEffect } from "react";
export default function Loyaltychash(props) {
const { show, handlemodalloyalty, contractid } = props;
useEffect(() => {
if (contractid != "") {
getdata();
setLoading(true);
carvin();
}
}, [show]);
return (
<div>
</div>
);
}
function carvin() {
console.log("innnn");
return (
<div>
<div>
<Modal show={true}>
<Modal.Header>
</Modal.Header>
<Modal.Body>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary">Close</Button>
<Button variant="primary">Save Changes</Button>
</Modal.Footer>
</Modal>
</div>
</div>
);
}
you are using show={true} for all time
<Modal show={show}>
and
return (
<div>
{carvin()}
</div>
);
My goal is to launch a modal pop-up during the event a button is clicked. I've been having issues making the Axios API call to the function that contains the modal. The process of the API call has been listed below:
First: This is the button where the Axios post request is made (addToCart) (works fine)
<button className="button is-primary" onClick={addToCart}>
ADD TO CART
</button>
Second: This is the Axios post request that makes a call to the modal pop-up (Example()) (works fine)
const addToCart = () => {
Axios.post(
//standard backend API call is made here
)
.then((res) => {
console.log("post called")
Example(); //I want to launch my modal when this state is reached
})
.catch((err) => {
if (err.response && err.response.status === 401) {
setIsLoggedIn(false);
}
});
Third: This is the modal that I'd like to popup but have been having issues rendering the function (Issue)
https://react-bootstrap.github.io/components/modal/
function Example() {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<Button variant="primary" onClick={handleShow}>
Launch demo modal
</Button>
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<Button variant="primary" onClick={handleClose}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
</>
);
}
render(<Example />);
I receive the following error:
Line 38:3: 'render' is not defined no-undef
How can I properly render my modal pop-up?
Instead of having a show state in your Example component, receive this data in a prop. In addition, you'll also want to pass some callbacks to the component to be able to react to certain events (e.g. clicking "Close" or "Save Changes").
I'd do the following:
const Example = ({ show, onClose, onSave }) => (
<Modal show={show} onHide={onClose}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={onClose}>
Close
</Button>
<Button variant="primary" onClick={onSave}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
)
This way you could always render the Example component in some parent component and show it conditionally, like so:
const SomeParentComponent = () => {
const [showExample, setShowExample] = useState(false)
const addToCart = () => {
Axios.post("http://example.com/api/add-to-cart")
.then((res) => {
console.log("post called")
setShowExample(true)
})
.catch((err) => {
if (err.response && err.response.status === 401) {
setIsLoggedIn(false);
}
})
}
return (
<>
<button className="button is-primary" onClick={addToCart}>
ADD TO CART
</button>
<Example
show={showExample}
onClose={() => setShowExample(false)}
onSave={() => setShowExample(false)}
/>
</>
)
}
I am trying to create a modal that I can reuse/call from multiple components. I want the modal to display in app.js but the button call is on another component.
Once I am able to implement one, I can but button on other components and call same modal instead of having to create the same modal for each component
<div className="App">
<HeroSlider />
<HowItWorks />
<Modal />
<Footer />
</div>
The modal button is on this component(HeroSlider). Once its click it will call the modal component and display it in app.js
import React, { useState } from "react";
import Header from './Header'
function HeroSlider(props) {
const [show, setShow] = useState(false);
const modalShow = () => setShow(true);
const openIsAccount = () => {
}
return (
<div className="jumbotron" id="jumbotron2" >
<button type="button" className="btn btn-primary" id="shoutBtn" onClick={modalShow}><span>Get Started</span>
</button>
</div>
);
}
export default HeroSlider;
Here is the Modal.js
const IsAccountOpen = (props) => {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<Modal show={props.show} onHide={handleClose} backdrop="static" keyboard={false}>
<Modal.Header closeButton>
<Modal.Title>Modal title</Modal.Title>
</Modal.Header>
<Modal.Body>
I will not close
</Modal.Body>
</Modal>
</>
);
};
export default IsAccountOpen
You need to add a function in the app.js to handle the click on the button, so the function will change the state show to true, and you will pass the state to your modal, like this:
App.js
[showState, setShowState] = useState(false)
buttonClickedHandler = () => {
setShowState((showState) => showState = !showState )
}
<div className="App">
<HeroSlider buttonClicked={buttonClickedHandler} />
<HowItWorks />
<Modal show={showState} buttonClicked={buttonClickedHandler} />
<Footer />
</div>
HeroSlider.js
import React, { useState } from "react";
import Header from './Header'
function HeroSlider(props) {
const [show, setShow] = useState(false);
const modalShow = () => setShow(true);
const openIsAccount = () => {
}
return (
<div className="jumbotron" id="jumbotron2" >
<button type="button" className="btn btn-primary" id="shoutBtn" onClick={props.buttonClicked}><span>Get Started</span>
</button>
</div>
);
}
export default HeroSlider;
IsAccountOpen.js
const IsAccountOpen = (props) => {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<Modal show={props.show} onHide={props.buttonClicked} backdrop="static" keyboard={false}>
<Modal.Header closeButton>
<Modal.Title>Modal title</Modal.Title>
</Modal.Header>
<Modal.Body>
I will not close
</Modal.Body>
</Modal>
</>
);
};
export default IsAccountOpen
I think the best solution is to use redux, because you will need to access and update the state from different components, you shouldn't use context API because the state changes frequently and you will hit the performance.
You'll need to extract the state to App level, so that this can be shared to components. You can do this with useState, or using context & custom hooks if you want to make it very clean. But do it with useState on first.
HeroSlider should receive modalShow function in it's props.
Modal.js should receive the show state as props.
I have the following Nextjs page using React bootstrap modal and a MUI datatables component:
const Start = () => {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const options = {
onTableInit: rowData,
onRowClick: rowData => Testing(rowData),
}
return (
<Layout>
<Modal show={show} onHide={handleClose}>
<Modal.Header>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>
Modal content
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
</Modal.Footer>
</Modal>
<MUIDataTable
title={"Datatable with modal onRowClick"}
data={data}
columns={columns}
options={options}
responsive="scrollFullHeight"
/>
</Layout>
)
}
export default Start;
The bootsrap modal works fine and opens onRowClick, I am also able to console log the rowData in a function when clicking a certain row:
function Testing(rowData) {
console.log(rowData)
);
I would like to achieve passing this rowData to the bootstrap modal accordingly when clicked on certain row.
I know I should be using the mapping, since it's an JSON object
{rowData.map(item => {
return <li key={item}>{item}</li>
}
)}
But how to integrate this into my current system? I get the error on rowData is not a function.
In my parent class I have rendered a childclass compoment and passed another component to it as a prop and in the childclass component I want to load that component.
<EditRecordModal
show={this.state.showEditModal}
onHide={this.handleModalClose}
handleModalClose={this.handleModalClose}
dialogClassName="width-9x"
modalTitle="Edit data"
onUpdate={this.handleUpdate}
record={letter}
component={NewLetterEntryForm} >
</EditRecordModal>
export const EditRecordModal = (props) => {
return (
<Modal show={props.show} onHide={props.onHide} dialogClassName={props.dialogClassName}>
<Modal.Header closeButton>
<Modal.Title>{props.modalTitle}</Modal.Title>
</Modal.Header>
<Modal.Body>
// here I want to load that props.component like this
// <NewLetterEntryForm showPageHead={false} mode="edit" record={props.record} onUpdate={props.onUpdate} />
</Modal.Body>
<Modal.Footer>
<Button onClick={props.handleModalClose}>Close</Button>
</Modal.Footer>
</Modal>
)
}
I tried this but it won't work....still
export const EditRecordModal = (props) => {
const childComponent = props.component
return (
<Modal show={props.show} onHide={props.onHide} dialogClassName={props.dialogClassName}>
<Modal.Header closeButton>
<Modal.Title>{props.modalTitle}</Modal.Title>
</Modal.Header>
<Modal.Body>
{React.Children.map(childComponent, (child, i) => {
console.log(child)
return child
})}
</Modal.Body>
<Modal.Footer>
<Button onClick={props.handleModalClose}>Close</Button>
</Modal.Footer>
</Modal>
)
}
I am not sure why you need to pass child component as a props from the parent component. but if you want to use React.Children API, you should use like this:
<EditRecordModal
show={this.state.showEditModal}
onHide={this.handleModalClose}
handleModalClose={this.handleModalClose}
dialogClassName="width-9x"
modalTitle="Edit data"
onUpdate={this.handleUpdate}
record={letter}
>
<NewLetterEntryForm
//some your props
/>
</EditRecordModal >
and you also need to import your child component class before using it, add this line to the import area in your code: import NewLetterEntryForm from 'yourPathTo NewLetterEntryForm'