Component is not defined in react? - javascript

using login function as component throws an error like this:
'LoginModal' is not defined react/jsx-no-undef
I dont know why this happening.
Thanks in advance.
export default class Login extends Component {
state={
loading: false,
modalShow: false,
clicked: false,
password:''
}
LoginModal = () => {
return <Modal {...this.props} size="lg" aria-labelledby="contained-modal-title-vcenter">
<Modal.Header closeButton>An otp has been sent to your Email!</Modal.Header>
<p>something...</p>
<Button variant="outline-primary" onClick={this.setState({modalShow:false})} >Change Password</Button>
</Modal>
}
handleForgetPassword = () => {
this.setState({modalShow: true})
}
handleSubmit = (event) => {
.....
}
render() {
return (
<div>
<div id="login-wrapper">
<p onClick={this.handleForgetPassword} className="forgot-password">forgot password?</p>
</div>
</div>
<LoginModal
show={this.state.modalShow}
onHide={() => this.setState({modalShow:false})}/>
</div>
)
}
}

You should initialize the state in the constructor
https://reactjs.org/docs/react-component.html#constructor
constructor(props) {
super(props);
this.state={
loading: false,
modalShow: false,
clicked: false,
password:''
}
Also, fix the render method as it's having a missing , or an extra closing tag
render() {
return (
<div>
<div id="login-wrapper">
<p onClick={this.handleForgetPassword} className="forgot-password">forgot password?</p>
</div>
<LoginModal
show={this.state.modalShow}
onHide={() => this.setState({modalShow:false})}/>
</div>
)
}

You're not referencing LoginModal correctly. You should do something like this instead:
Create a standalone component and then pass props to it
const LoginModal = ({onClick, ...props}) => {
return <Modal {...props} size="lg" aria-labelledby="contained-modal-title-vcenter">
<Modal.Header closeButton>An otp has been sent to your Email!</Modal.Header>
<p>something...</p>
<Button variant="outline-primary" onClick={onClick} >Change Password</Button>
</Modal>
}

Try this way
return (
<div>
......
{this.LoginModal()}
</div>
)

Related

Why is submitting a form resetting my state?

I am making a Kanban board project. It comes with a log in screen. I've added a button that I want to use to add new tasks to the board. However, when I submit to that button, it resets my email state to blank, which is my condition to returning to the log-in screen. Why? How can I prevent this? Any advice would be appreciated.
App.js
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
initialData,
email: this.props.email,
password: this.props.password,
showForm: false,
};
this.logOut = this.logOut.bind(this);
}
logOut() {
console.log("Logged out");
this.setState({ email: "", password: "" });
}
render() {
const { showForm } = this.state;
if (this.state.email == "") {
return <LogIn />;
} else {
{
//console.log(this.state);
}
return (
<DragDropContext onDragEnd={this.onDragEnd}>
<Container>
{this.state.initialData.columnOrder.map((columnId) => {
const column = this.state.initialData.columns[columnId];
const tasks = column.taskIds.map(
(taskId) => this.state.initialData.tasks[taskId]
);
return <Column key={column.id} column={column} tasks={tasks} />;
})}
</Container>
<button onClick={this.logOut}>Log Out</button>
<button onClick={() => this.hideComponent("showForm")}>
Create Task
</button>
<Container>
<div>
{showForm && <CreateForm onSubmit={(value) => alert(value)} />}
</div>
</Container>
</DragDropContext>
);
}
}
}
CreateForm.js
class CreateForm extends React.Component {
render() {
console.log("form");
return (
<form onSubmit={this.handleSubmit}>
<label>
Content:
<input type="text" />
</label>
<input type="submit" value="Submit" onSubmit={event => props.onSubmit(event.target.value)}/>
</form>
);
}
}
export default CreateForm;
handleSubmit(event) {
event.preventDefault(); // we need this for avoid your behavior
// your code
}

How to change the state of the child component?

I am creating a simple application using react and I have two components: Form and Modal. The Modal should be opened when the Form is submitted. How to change the state of the Modal component to achieve this ?
This is the code for the Form.js compent:
import Modal from './Modal'
export default function Form() {
const handleSubmit = (e) => {
e.preventDefault()
}
return (
<form onSubmit={handleSubmit}>
<SuccessModal />
<div className='mt-1'>
...
</form>
)}
This is the code for the Modal.js compent:
export default function Modal() {
const [open, setOpen] = useState(false)
return (
<Transition.Root show={open} as={Fragment}>
<Dialog
as='div'
static
open={open}
onClose={setOpen}
>
...
</Dialog>
</Transition.Root>
I tried to pass this state as a property, but I think I'm doing something wrong. I would be very grateful if any of you could explain to me the principle of how this works.
You can have modal state in Form.js and then pass the state as props to Modal.js.
On Form submit set the modal state.
Form.js
import Modal from './Modal'
export default function Form() {
const [open, setOpen] = useState(false)
const handleSubmit = (e) => {
e.preventDefault()
...
setOpen(true);
}
return (
<>
<form onSubmit={handleSubmit}>
<SuccessModal />
<div className='mt-1'>
...
</form>
{open && <Modal open={open} setOpen={setOpen} />}
</>
)}
Modal.js
export default function Modal({ open, setOpen }) {
return (
<Transition.Root show={open} as={Fragment}>
<Dialog
as='div'
static
open={open}
onClose={setOpen}
>
...
</Dialog>
</Transition.Root>
the state controller useState should be in the parent, not the Modal.
Then you can simply use a prop to define the open state.
One way we do this at my work is creating a custom hook for it:
// stateless modal component
export default function Modal({ open }) {
return (
<Transition.Root show={open} as={Fragment}>
<Dialog
as='div'
static
open={open}
onClose={setOpen}
>
...
</Dialog>
</Transition.Root>
}
// custom hook
export function useModal({ initialState }) {
const [open, setOpen] = useState(initialState)
return {
component: <Modal open={open} />,
setOpen,
}
}
// parent code
import { useModal } from './Modal'
export default function Form() {
const modal = useModal(false)
const handleSubmit = (e) => {
e.preventDefault()
modal.setOpen(true)
}
return (
<form onSubmit={handleSubmit}>
{modal.component}
<div className='mt-1'>
...
</form>
)}
You can try lifting the state of the child (Modal) to the state of the parent (Form). Refer this
You don't use state for show or hide Modal component. Use the props. With props components will be working like this:
import Modal from './Modal'
interface IFormProps {}
interface IFormState {
isModalOpen: boolean
}
export class Form extends React.Component<IFormProps, IFormState> => {
state: IFormState = {
isModalOpen: false,
}
const handleSubmit = (e): void => {
this.setState({ isModalOpen: true })
e.preventDefault()
}
const handleModalClose = (): boolean => {
this.setState({ isModalOpen: false })
}
return (
<form onSubmit={handleSubmit}>
<Modal isOpen={this.state.isModalOpen} handleClose={this.handleModalClose} />
<div className='mt-1'>
...
</form>
)}
interface IModalProps {
isOpen: boolean
handleClose: () => boolean
}
interface IModalState {}
export class Modal extends React.Compnent<IModalProps, IModalState> {
const { isOpen, handleClose } = this.props
return (
<Transition.Root show={isOpen} as={Fragment}>
<Dialog
as='div'
static
open={isOpen}
onClose={handleClose}
>
...
</Dialog>
</Transition.Root>

Semantic UI modal onOpen/onClose not working

I want to let the modal close itself after 3000ms.
But the onOpen callback is not called at all when the modal is open.
Is there a workaround for this?
I put console.log in onOpen and onClose, but nothing is appearing in the console.
import React, { Component } from 'react'
import { Modal, Button, Header } from 'semantic-ui-react'
export default class YourTurnModal extends Component {
constructor(props) {
super(props)
this.state = {
modalState: this.props.isYourTurn,
}
this.handleOpen = this.handleOpen.bind(this)
this.handleClose = this.handleClose.bind(this)
}
componentWillReceiveProps(nextProps) {
this.setState({ modalState: nextProps.isYourTurn })
}
render() {
return (
<div>
<Modal
onOpen={() => {
console.log("Open", this.state.modalState);
this.setState({
modalState: true
},()=>{
setTimeout(() => {this.setState({ modalState: false });}, 3000);});
}}
open={this.state.modalState}
onClose={() => {this.setState({ modalState: false });console.log("here")}}
>
<Modal.Content style={{ borderless: 'true' }}>
<Header>
Your turn!
</Header>
<Button
color="green"
onClick={() => {this.setState({ modalState: false })}}>
close
</Button>
</Modal.Content>
</Modal>
</div>
)
}
}
I tried with:
<YourTurnModal isYourTurn={true} />

React modal opens second modal but second modal doesn't work

I'm working on A React project with GraphQl back-end. I have a modal where a user can view more details about a subject. In that modal you can click delete which opens a new modal where you need to confirm if you wan't to delete. When yes is pressed it should be deleted and the modal should close. When no is pressed the modal should just close. The deleting of the subject works. If I press yes is deletes it but the modal doesn't close and when I press no the modal also doesn't close. Can anyone explain why and how I can fix this?
parent modal:
class CalenderModal extends React.Component {
constructor(props) {
super(props);
this.state = {
openDeleteAppointment: false,
};
this.openDeleteAppointment = this.openDeleteAppointment.bind(this);
}
handleRemove = () => {
this.props.onRemove();
}
openDeleteAppointment() {
this.setState({
openDeleteAppointment: true,
})
}
render() {
return (
<React.Fragment>
<div className="customModal">
<div className="modal-header">
<h5 className="customModal__text"> Appointment summary</h5>
<button className="btn modal__button__red" onClick={() => { this.openDeleteAppointment() }}>Delete</button>
{this.state.openDeleteAppointment &&
<DeleteAppointmentModal appointment={this.state.id} onHide={() => this.setState({ openDeleteClient: false, id: null })} show />}
</div>
<div className="modal-container">
<div className="summary">
<button className="btn modal__button__cancel" onClick={this.handleRemove}>Cancel</button>
</div>
</div>
}
</React.Fragment>
);
}
export default CalenderModal;
child modal:
class DeleteAppointmentModal extends React.Component {
constructor(props) {
super(props);
this.state = {
id: this.props.appointment,
};
}
render() {
const {id} = this.state
const DELETE_MUTATION = gql`
mutation DeleteMutation($id:ID! ) {
deleteAppointment(id:$id) {
id
}
}
`
console.log("delete id",this.state.id)
return (
<React.Fragment>
{
<Modal
{...this.props}
size="lg"
aria-labelledby="contained-modal-update-client"
centered
>
<Modal.Header closeButton >
<Modal.Title id="contained-modal-title-vcenter" className="tittle">Delete appointment </Modal.Title>
</Modal.Header>
<Modal.Body>
<div className="delete-content">
Are you sure you want to delete this appointment?
</div>
</Modal.Body>
<Modal.Footer>
<button onClick={() => this.props.onHide() } className="btn no">No</button>
<Mutation mutation={DELETE_MUTATION}
variables={{id}}>
{/* onCompleted={() => this.props.history.push('/')} */}
{deleteMutation =>
<button onClick={() => { deleteMutation(); this.props.onHide() }} className="btn yes">Yes</button>
}
</Mutation>
</Modal.Footer>
</Modal>
}
</React.Fragment>
);
}
}
export default DeleteAppointmentModal;
On "return" of parent component change the following row:
from:
<DeleteAppointmentModal appointment={this.state.id} onHide={() => this.setState({ openDeleteClient: false, id: null })} show />}
to:
<DeleteAppointmentModal appointment={this.state.id} onHide={() => { this.setState({ openDeleteAppointment: false, id: null }); handleRemove(); }} show />}
Hope it solved the problem.
From observation:
the show prop is always true. set show={this.state. openDeleteAppointment}
the onHide is not setting the right state. it should set openDeleteAppointment instead of openDeleteClient

Open modal from another component click in react js

I am using the basic component modal component of react - https://github.com/reactjs/react-modal
What I am trying to achieve is that I want to open the modal from another parent that has the modal imported.
Parent.js
<button onClick={() => this.refs.setState({modalIsOpen: true})}> - THIS BUTTON ELEMENT IS IN ANOTHER COMPONENT
Modal.js
import React from 'react';
import ReactDOM from 'react-dom';
import Modal from 'react-modal';
const customStyles = {
content : {
top : '50%',
left : '50%',
right : 'auto',
bottom : 'auto',
marginRight : '-50%',
transform : 'translate(-50%, -50%)'
}
};
class App extends React.Component {
constructor() {
super();
this.state = {
modalIsOpen: false
};
this.openModal = this.openModal.bind(this);
this.afterOpenModal = this.afterOpenModal.bind(this);
this.closeModal = this.closeModal.bind(this);
}
openModal() {
this.setState({modalIsOpen: true});
}
afterOpenModal() {
// references are now sync'd and can be accessed.
this.subtitle.style.color = '#f00';
}
closeModal() {
this.setState({modalIsOpen: false});
}
render() {
return (
<div>
<button onClick={this.openModal}>Open Modal</button>
<Modal
isOpen={this.state.modalIsOpen}
onAfterOpen={this.afterOpenModal}
onRequestClose={this.closeModal}
style={customStyles}
contentLabel="Example Modal"
>
<h2 ref={subtitle => this.subtitle = subtitle}>Hello</h2>
<button onClick={this.closeModal}>close</button>
<div>I am a modal</div>
<form>
<input />
<button>tab navigation</button>
<button>stays</button>
<button>inside</button>
<button>the modal</button>
</form>
</Modal>
</div>
);
}
}
export default App
I have read that this can be done using refs and changing the state of the modal. What exactly am I doing wrong here?
Thanks!
Can you try below code in parent
<button onClick={() => this._modal.openModal()}>click</button>
when you call your modal component use ref attribute then can call like above code.
<Modal ref={(modal) => { this._modal = modal; }} />
easy way, do this via props:
modal.js
import ....
<Modal
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
className={classes.modal}
open={this.props.handleOpen}
onClose={this.props.handleClose}
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 1000
}}
>
in your component that has the modal imported.
///some code here
state = {
isOpen: Boolean(false)
};
<externalElement onClick={() => this.setState({ isOpen: true })}>title ... </externalElement>
<importedModal
handleOpen={this.state.isOpen}
handleClose={() => this.setState({ isOpen: false })}
/>

Categories

Resources