I am trying to create a modal that handles updates, but it's not showing {this. state. value}
state={
name: '',
businessName: '',
show: false,
}
showModal(e) {
if (e) {
this.setState({ show: true });
}
}
showEditModal(e) {
const { user } = this.props.auth;
const email=user.email
axios.get(`/api/v1/auth/userdetails/${email}`)
.then(
(res) => {
console.log(res.data) // res.data actually has data from API
let user = res.data
this.setState ({
id:user.id,
name:user.name,
businessName:user.businessName,
})
this.setState({
show: true,
});
console.log(this.state.name) // i get undefined
},
(err) => {
alert('An error occured! Try refreshing the page.', err);
}
);
}
onChange = (e) => {
this.setState({ [e.target.name]: e.target.value });
};
onSubmit = (e) => {
e.preventDefault();
const {
_id,
name,
businessName,
} = this.state;
const userDetail = {
_id,
name,
businessName,
};
console.log(userDetail);
axios.post(`/api/v1/auth/update/${_id}`, userDetail).then(
(res) => {
Swal.fire({
title: 'Profile ',
text: 'Update successful!',
icon: 'success',
confirmButtonText: 'Ok'
})
},
(err) => {
alert('An error occured! Try submitting the form again.', err);
}
);
};
hideModal = () => {
this.setState({
show: false,
name:'',
businessName:'',
});
};
ModalForm=()=>{
return <div style={{ backgroundColor: 'white' }}>
<Modal
{...this.props}
show={this.state.show}
onHide={this.hideModal}
dialogClassName='custom-modal'
>
<Modal.Header closeButton>
<Modal.Title
id='contained-modal-title-lg '
className='text-center'
>
Update Profile
</Modal.Title>
</Modal.Header>
<Modal.Body className='modal-contentx'>
<Form horizontal onSubmit={this.onSubmit}>
<FormGroup controlId='formHorizontalEmail'>
<Col smOffset={4} sm={6}>
<FormControl
type='Text'
backgroundColor='grey'
placeholder='name'
name='name'
value={this.state.name}
onChange={this.onChange}
/>
</Col>
</FormGroup>
<FormGroup controlId='formHorizontalPassword'>
<Col smOffset={4} sm={6}>
<FormControl
type='text'
placeholder=''
name='businessName'
value={this.state.businessName}
onChange={this.onChange}
/>
</Col>
</FormGroup>
<FormGroup>
<Col smOffset={5} sm={6}>
<Button type='submit' bsStyle='primary'>
Add
</Button>
</Col>
</FormGroup>
</Form>
</Modal.Body>
</Modal>
</div>
<ButtonGroup>
<Button className="btn-fill" color="primary" type="submit">
Save
</Button>
<Button className="btn-fill" onClick={(e) => this.showEditModal(e)}>
Update
</Button>
</ButtonGroup>
}
render(){
return (
<div>
// Add form is placed here
</div>
<div>
// modal form is placed here
{this.ModalForm()}
</div>
)
}
the modal comes up onClick, but fails to show any value. When i do console.log(this.state.name) for instance i get undefined?!
I need the Modal to be populated with the value from the state. The response object from the console contains the data that i am using to update the state through setState().
i guess something is off though, but cant figure it out
Related
Hi i am trying to close a modal box from another component. I have a component with a list and other with a form.
The error that i get is:
Unhandled Rejection (TypeError): _this2.closeModal is not a function
The List file with the modal commands has:
closeModal = () => this.setState({ isOpen: false });
render() {
const { closeModal } = this.state
...
<Modal show={this.state.isOpen} onHide={this.closeModal}>
<Modal.Header closeButton>
<Modal.Title>Adicionar / Editar</Modal.Title>
</Modal.Header>
<Modal.Body>
<CategoryForm
id={this.state.id || null}
closeModal={closeModal}
/>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={this.closeModal}>
Close
</Button>
</Modal.Footer>
</Modal>
</>
// some code
}
the file with form, that will close the modal after saving info in the database is
class CategoryForm extends Component {
constructor(props) {
super(props)
this.state = {
closeModal: props.closeModal
}
}
handleSubmit(event) {
event.preventDefault()
let category = {
title: this.state.category.title,
}
Api.saveCategory(category, this.state.category.id)
.then(response => {
const [error, errors] = response
if (error) {
this.setState({
errors: errors
})
} else {
this.setState(
this.closeModal()
)
}
})
}
//some code
render() {
<Form onSubmit={this.handleSubmit} >
<FormGroup>
<Label for="title">Title</Label>
<Input type="text" name="title" id="title" value={category.title} placeholder="Enter title" onChange={this.setTitle} />
</FormGroup>
<FormGroup>
<Label for="slug">Slug</Label>
<Input type="text" name="slug" id="slug" value={category.slug} placeholder="Enter slug" onChange={this.setSlug} />
</FormGroup>
<Button color="success">Submit</Button>
</Form>
}
In the list file create a command that call the function close modal:
closeModal = () => this.setState({ isOpen: false });
addCategory() {
this.closeModal()
}
render() {
...
<Modal show={this.state.isOpen} onHide={this.closeModal}>
<Modal.Header closeButton>
<Modal.Title>Adicionar / Editar</Modal.Title>
</Modal.Header>
<Modal.Body>
<CategoryForm
id={this.state.id || null}
addCategory={this.addCategory}
/>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={this.closeModal}>
Close
</Button>
</Modal.Footer>
</Modal>
</>
// some code
}
In the form, props the function at the handleSubmit:
handleSubmit(event) {
event.preventDefault()
let category = {
title: this.state.category.title,
slug: this.state.category.slug,
}
Api.saveCategory(category, this.state.category.id)
.then(response => {
const [error, errors] = response
if (error) {
this.setState({
errors: errors
})
} else {
this.setState(
)
}
})
const form = event.target;
this.props.addCategory( id, slug, title);
form.reset();
}
New to React. I am trying to find out how I can close a Modal after the Form Submit event has been triggered.
export default class UserAdmin extends Component {
constructor(props) {
super(props);
this.state = {
show_user_modal : false
}
}
// Handle User Modal
handleUserModalOpen = () => {
this.setState({ show_user_modal: true});
}
handleUserModalClose = () => {
this.setState({ show_user_modal: false});
}
render() {
const { show_user_modal } = this.state;
return (
<Content>
<div className="site-layout-background">
<div className="contentBody">
<Button type="primary"onClick={this.handleUserModalOpen}>
Add User
</Button>
{show_user_modal && <AddUserModal handleClose={this.handleUserModalClose}/>}
</div>
</div>
</Content>
)
}
}
This works perfectly to open and close the modal, and the submit is working perfectly inside the addUserModal, however I am unsure how I should close the modal after this has been completed. I have tried to setState() from the parent to the child but it doesn't want to even then show the modal. Any help appreciated!
**Adding addUserModal function:
function AddUserModal({handleClose}){
const [addUserForm] = Form.useForm();
/** POST User */
const postUser = (values) => {
axios.post('http://localhost:5000/portal/add-user', values)
.then(res => {
if (res.status === 200) {
console.log(res.data);
}
})
};
return(
<Modal title="Add User" okText="Confirm" visible={true} onCancel={handleClose}
onOk={() => {
addUserForm
.validateFields()
.then((values) => {
postUser(values);
addUserForm.resetFields();
})
.catch((info) => {
console.log('Validate Failed:', info);
});
}}
>
<Form
form={addUserForm}
name="addUserForm"
labelCol={{span: 5,}}
wrapperCol={{span: 16,}}
initialValues={{remember: false,}}
>
<Form.Item label="Username" name="username"
rules={[
{
required: true,
message: 'Please input a username!',
},
]}
>
<Input />
</Form.Item>
<Form.Item label="Email" name="email"
rules={[
{
required: true,
message: 'Please input an email address',
},
]}
><Input />
</Form.Item>
<Form.Item label="Password" name="password"
rules={[
{
required: true,
message: 'Please input a password',
},
]}
><Input.Password />
</Form.Item>
</Form>
</Modal>
);
}
export default AddUserModal;
Your modal has visible property always set to true. Pass show_user_modal variable to the child and use it in the modal visiblestate. The {show_user_modal && <AddUserModal... is unnecessary
handleClose is calling handleUserModalClose. I think the issue is something else. So you can try calling handleClose in .then of your API call and pass the visible prop as well
export default class UserAdmin extends Component {
constructor(props) {
super(props);
this.state = {
show_user_modal : false
}
}
// Handle User Modal
handleUserModalOpen = () => {
this.setState({ show_user_modal: true});
}
handleUserModalClose = () => {
this.setState({ show_user_modal: false});
}
render() {
const { show_user_modal } = this.state;
return (
<Content>
<div className="site-layout-background">
<div className="contentBody">
<Button type="primary"onClick={this.handleUserModalOpen}>
Add User
</Button>
{show_user_modal && <AddUserModal visible={show_user_modal} handleClose={this.handleUserModalClose}/>}
</div>
</div>
</Content>
)
}
}
and use it in AddUserModal
function AddUserModal({visible, handleClose}){
const [addUserForm] = Form.useForm();
/** POST User */
const postUser = (values) => {
axios.post('http://localhost:5000/portal/add-user', values)
.then(res => {
if (res.status === 200) {
console.log(res.data);
handleClose();
}
})
};
return(
<Modal title="Add User" okText="Confirm" visible={visible} onCancel={handleClose}
onOk={() => {
addUserForm
.validateFields()
.then((values) => {
postUser(values);
addUserForm.resetFields();
})
.catch((info) => {
console.log('Validate Failed:', info);
});
}}
>
<Form
form={addUserForm}
name="addUserForm"
labelCol={{span: 5,}}
wrapperCol={{span: 16,}}
initialValues={{remember: false,}}
>
<Form.Item label="Username" name="username"
rules={[
{
required: true,
message: 'Please input a username!',
},
]}
>
<Input />
</Form.Item>
<Form.Item label="Email" name="email"
rules={[
{
required: true,
message: 'Please input an email address',
},
]}
><Input />
</Form.Item>
<Form.Item label="Password" name="password"
rules={[
{
required: true,
message: 'Please input a password',
},
]}
><Input.Password />
</Form.Item>
</Form>
</Modal>
);
}
export default AddUserModal;
Currently a user can enter first, lastname, and employee id. When it submits it renders an iteration of employees with the first, last, and employee id.
The problem is when you click edit, it edits the data but it will edit all of the fields for every object in the employees iteration.
How can I fix the code so that it will edit just that particular object within that iteration.
Home component
........
class Login extends Component {
constructor(props) {
super(props);
this.state = {
activeTab: '3',
firstName: '',
lastName: '',
employeeID: '',
employees: [],
Edit: false,
updatedFirst: '',
updatedLast:'',
updatedEmployeeID: ''
};
}
toggle = (tab) => {
if(this.state.activeTab !== tab){
this.setState({
activeTab: tab
})
}
}
onSubmit = (e) => {
e.preventDefault();
const {firstName, lastName, employeeID} = this.state
const ourForm ={
firstName: firstName,
lastName: lastName,
employeeID: employeeID,
// we need an id to so that it can be edited properly
}
this.setState({
employees: [...this.state.employees,ourForm]
}, () => {
console.log(this.state.employees)
})
}
onChange = (e) => {
e.preventDefault()
// e.preventDefault();
this.setState({
[e.target.name]: e.target.value,
});
}
updatedChange = (e) => {
e.preventDefault()
// e.preventDefault();
this.setState({
[e.target.name]: e.target.value,
});
}
onEdit = (e) => {
e.preventDefault();
this.setState({
Edit: !this.state.Edit
})
}
onReset = (e) => {
e.preventDefault();
this.setState({
firstName: '',
lastName: '',
employeeID: ''
})
}
render(){
return (
......
<MyForm
onSubmit={this.onSubmit}
onChange={this.onChange}
onReset={this.onReset}
firstName={this.state.firstName}
lastName={this.state.lastName}
employeeID={this.state.employeeID}
/>
</Col>
</Row>
</TabPane>
</TabContent>
</Container>
<List
employees={this.state.employees}
Edit={this.state.Edit}
onEdit ={this.onEdit}
onChange={this.onChange}
updatedEmployeeID={this.state.updatedEmployeeID}
updatedFirst={this.state.updatedFirst}
updatedLast={this.state.updatedLast}
/>
</div>
);
}
}
export default Login;
Form.js
import React, {Component} from 'react';
import { Col, Form, FormGroup, Label, Input, Button } from 'reactstrap';
const MyForm = (props) => {
return(
<Form style={{ margin: '30px 0px'}}>
<FormGroup row>
<Label for="firstName" sm={2} size="sm">First Name:</Label>
<Col sm={10}>
<Input type="text" onChange={props.onChange} value={props.firstName} name="firstName" id="exampleEmail" placeholder="Enter First Name"/>
</Col>
</FormGroup>
<FormGroup row>
<Label for="lastName" sm={2} size="sm">Last Name:</Label>
<Col sm={10}>
<Input type="text" onChange={props.onChange} value={props.lastName} name="lastName" id="exampleEmail2" placeholder="Enter Last Name" />
</Col>
</FormGroup>
<FormGroup row>
<Label for="Employee ID" sm={2} size="sm">Employee ID:</Label>
<Col sm={5}>
<Input type="text" onChange={props.onChange} value={props.employeeID} name="employeeID" id="exampleEmail2" placeholder="Enter Employee ID" />
</Col>
</FormGroup>
<FormGroup row>
<Col sm={12}>
<div className="float-right">
<Button onClick={props.onSubmit} size="lg" style={{ margin: '0px 5px'}} color="secondary">Add</Button>
<Button onClick={props.onReset} size="lg" style={{ margin: '0px 5px'}}color="warning">Reset</Button>
</div>
</Col>
</FormGroup>
<hr></hr>
<FormGroup row>
<Col sm={4}>
<Input type="text" name="search" id="exampleEmail2" placeholder="Search" />
</Col>
<Col sm={8}>
<Label for="sort" sm={2} size="sm">Sort:</Label>
<Button onClick={props.onSubmit} size="lg" style={{ margin: '0px 5px'}} color="secondary">First Name</Button>
<Button onClick={props.onSubmit} size="lg" style={{ margin: '0px 5px'}} color="secondary">Last Name</Button>
<Button onClick={props.onSubmit} size="lg" style={{ margin: '0px 5px'}} color="secondary">ID</Button>
</Col>
</FormGroup>
</Form>
)
}
export default MyForm;
List component
import React, {Component, Fragment} from 'react';
import { Col, Form, FormGroup, Label, Input, Button } from 'reactstrap';
const List = (props) => {
return(
<Fragment>
{props.employees.map( (item, i) => (
<div style={{ margin: '40px 0px'}} key={i}>
<hr style={{ border:'1px dashed #000'}}></hr>
<div className="float-right">
<Button onClick={props.onEdit} size="lg" style={{ margin: '0px 5px'}} color="secondary">{props.Edit ? 'Save': 'Edit'}</Button>
<Button size="lg" style={{ margin: '0px 5px'}}color="secondary">Delete</Button>
</div>
<FormGroup row>
<Col sm={5}>
{props.Edit ? (
<Input type="text" onChange={props.onChange} value={ props.updatedFirst ? props.updatedFirst : item.firstName } name="updatedFirst" placeholder="Enter First Name"/>
):(
<div>
{props.updatedFirst ? props.updatedFirst : item.firstName }
</div>
)}
</Col>
</FormGroup>
<FormGroup row>
<Col sm={5}>
{props.Edit ? (
<Input type="text" onChange={props.onChange} value={ props.updatedEmployeeID ? props.updatedEmployeeID : item.employeeID} name="updatedEmployeeID" placeholder="Enter EmployeeID"/>
):(
<div>
{props.updatedEmployeeID ? props.updatedEmployeeID : item.employeeID}
</div>
)}
</Col>
</FormGroup>
<FormGroup row>
<Col sm={5}>
{props.Edit ? (
<Input type="text" onChange={props.onChange} value={ props.updatedLast ? props.updatedLast: item.lastName} name="updatedLast" placeholder="Enter Last Name"/>
):(
<div>
{props.updatedLast ? props.updatedLast : item.lastName}
</div>
)}
</Col>
</FormGroup>
</div>
))}
</Fragment>
)
}
export default List;
The following example shows how to pass a handler and set the state accordingly.
For good measure I separated the logic and the presentation, the presentational components are pure components using React.memo.
//A container should only contain the logic
class EmployeesContainer extends React.Component {
state = {
employees: [{ name: '' }, { name: '' }, { name: '' }],
};
//define what needs to happen if you click edit on an
// employee
onEdit = index => {
//edit will be called with the index of the employee
// the Employees component owns the list of employees
// so it will have to make changes to it
this.setState({
employees: this.state.employees.map((employee, i) =>
i === index ? { ...employee, edit: true } : employee
),
});
};
//Same idea as onEdit, index needs to be passed to indicate
// what employee needs to be changed
onChange = (index, e) => {
this.setState({
employees: this.state.employees.map((employee, i) =>
i === index
? { ...employee, name: e.target.value }
: employee
),
});
};
render() {
return (
<Employees
employees={this.state.employees}
onEdit={this.onEdit}
onChange={this.onChange}
/>
);
}
}
//The Employees presentational component, contains the jsx
// you can make it a pure component by using React.memo
const Employees = React.memo(
({ employees, onEdit, onChange }) => (
<div>
{employees.map((employee, index) => (
<EmployeeContainer
key={index}
index={index}
employee={employee}
onEdit={onEdit}
onChange={onChange}
/>
))}
</div>
)
);
//Make this a container as well because it does more
// than only produce jsx
class EmployeeContainer extends React.Component {
state = {};
//create onChange and onEdit only when index changes
// this will prevent unnecessary renders
static getDerivedStateFromProps(props, state) {
const { index, onChange, onEdit } = props;
if (state.index !== index) {
return {
index,
onChange: e => onChange(index, e),
onEdit: () => onEdit(index),
};
}
return null;
}
render() {
const { employee } = this.props;
const { onChange, onEdit } = this.state;
return (
<Employee
employee={employee}
onChange={onChange}
onEdit={onEdit}
/>
);
}
}
//presentational component, is also pure component
const Employee = React.memo(
({ employee, onChange, onEdit }) => (
<div>
{employee.edit ? (
<input
type="text"
value={employee.name}
onChange={onChange}
/>
) : (
<button onClick={onEdit}>edit</button>
)}
</div>
)
);
I don’t think onSubmit is updating employees correctly. You shouldn’t use this.state inside setState.
this.state inside setState ReactJS
Try this..
this.setState(prevState => ({
employees: [...prevState.employees, ourForm]
}, () => {
console.log(this.state.employees)
}))
Still new in React and im in the middle of my practice creating table components, the task is: input, delete and edit data.
input data row is working
delete data row is working
edit data not working,
i can manage to get the value, but i can't edit it.
the code still messy too, but it works from point 1 to 2.
Here is the code. Hope you guys can point out my mistakes and maybe some tips to tidy up this code to make it more cleaner.
Thanks
//Table.js//
import React, { Component } from 'react'
import { Table, Icon, Button, Modal, Form } from 'semantic-ui-react'
import 'semantic-ui-css/semantic.min.css'
import { DateInput } from 'semantic-ui-calendar-react'
import './Tables.css'
var database = [
{
DocNum: 123,
DocTyp: 'Permit',
DocName: 'Permit A',
SignDate: '2007-11-05',
ExprDate: '2012-11-05'
},
{
DocNum: 456,
DocTyp: 'Permit',
DocName: 'Permit C',
SignDate: '2010-02-11',
ExprDate: '2015-02-11'
},
{
DocNum: 789,
DocTyp: 'Contract',
DocName: 'Contract Z',
SignDate: '2017-06-08',
ExprDate: '2022-06-08'
}
]
const options = [
{ key: 1, text: 'Permit', value: 'Permit' },
{ key: 2, text: 'Contract', value: 'Contract' },
]
const initialState = { open: false,
open2: false,
open3: false,
open4: false,
DocNum: '',
DocTyp: '',
DocName: '',
SignDate: '',
ExprDate: '',
del:'',
edit:''
}
function Addbtn ({ onShow3 }) {
return(
<Button content='Add Document' icon='plus' labelPosition='left' color="green" onClick={onShow3} />
)
}
function InputData ({ onChange, onSubmit, DataInput}) {
return (
<Form className="InputContainer">
<Form.Input label="Document Number" type="text" name="DocNum" onChange={onChange} />
<Form.Select label="Document Type" type="text" name="DocTyp" onChange={onChange} options={options} />
<Form.Input label="Document Name" type="text" name="DocName" onChange={onChange} />
<DateInput label="Signed Date" name="SignDate" onChange={onChange} value={DataInput[0].SignDate}/>
<DateInput label="Expired Date" name="ExprDate" onChange={onChange} value={DataInput[0].ExprDate}/>
</Form>
)
}
function EditData ({ onChange, onSubmit, DataEdit }) {
return (
<Form className="InputContainer">
<Form.Input label="Document Number" type="text" name="DocNum" onChange={onChange} value={DataEdit.DocNum}/>
<Form.Select label="Document Type" type="text" name="DocTyp" onChange={onChange} options={options} value={DataEdit.DocTyp} />
<Form.Input label="Document Name" type="text" name="DocName" onChange={onChange} value={DataEdit.DocName} />
<DateInput label="Signed Date" name="SignDate" onChange={onChange} value={DataEdit.SignDate}/>
<DateInput label="Expired Date" name="ExprDate" onChange={onChange} value={DataEdit.ExprDate}/>
</Form>
)
}
function RowData(props) {
const database = props.database
const RowList = database.map((data)=>
<Table.Row key={data.DocNum}>
<Table.Cell>{data.DocNum}</Table.Cell>
<Table.Cell>{data.DocTyp}</Table.Cell>
<Table.Cell>{data.DocName}</Table.Cell>
<Table.Cell>{data.SignDate}</Table.Cell>
<Table.Cell>{data.ExprDate}</Table.Cell>
<Table.Cell className="icon" collapsing>
<Icon color='yellow'
name='edit'
link
onClick={()=>props.onShow(data)}
/>
<Icon color='red'
name='trash'
link
key={data.DocNum}
onClick={()=>props.onShow2(data)}
/>
</Table.Cell>
</Table.Row>
)
return RowList
}
class TableComponent extends Component{
state = initialState
show = (data) => {
this.setState({ open: true,
edit: data })
}
show2 = (data) => {
this.setState({ open2: true,
del: data })
}
show3 = () => {
this.setState({ open3: true })
}
show4 = (data) => {
this.setState({ open4: true })
this.close()
}
close = () => {
this.setState({ open: false })
}
close2 = () => {
this.setState({ open2: false })
}
close3 = () => {
this.setState({ open3: false })
}
close4 = () => {
this.setState({ open4: false })
}
InputChange = (e, DataInput) => {
this.setState({ [DataInput.name]: DataInput.value })
}
SearchDel = () =>{
for(let i=0; i<database.length; i++){
if (this.state.del === database[i])
return database.splice(i, 1)}
}
DelData = () =>{
return ( this.SearchDel(),
this.close2())
}
Submit = (data) => {
return (database.push(data),
this.close3())
}
render(){
return(
<div className='MainContainer'>
<div className="TblContainer">
<div className="AddButton">
<Addbtn onShow3={this.show3}/>
</div>
<Table color="red" celled >
<Table.Header>
<Table.Row>
<Table.HeaderCell collapsing>Document Number</Table.HeaderCell>
<Table.HeaderCell width={2}>Document Type</Table.HeaderCell>
<Table.HeaderCell width={6}>Document Name</Table.HeaderCell>
<Table.HeaderCell collapsing>Signed Date</Table.HeaderCell>
<Table.HeaderCell collapsing>Expired Date</Table.HeaderCell>
<Table.HeaderCell collapsing />
</Table.Row>
</Table.Header>
<Table.Body>
<RowData database={database} onShow={this.show} onShow2={this.show2} />
</Table.Body>
</Table>
<Modal open={this.state.open} onClose={this.state.close} id="Modal1">
<Modal.Header>Edit Data</Modal.Header>
<Modal.Content>
<p>Are you sure you want to edit this?</p>
</Modal.Content>
<Modal.Actions>
<Button negative onClick={this.close}>No</Button>
<Button positive onClick={this.show4}>Yes</Button>
</Modal.Actions>
</Modal>
<Modal open={this.state.open2} onClose={this.state.close2} value={this.state} id="Modal2">
<Modal.Header>Delete Data</Modal.Header>
<Modal.Content>
<p>Are you sure you want to delete this?</p>
</Modal.Content>
<Modal.Actions>
<Button negative onClick={this.close2}>No</Button>
<Button positive onClick={()=>this.DelData()}>Yes</Button>
</Modal.Actions>
</Modal>
<Modal open={this.state.open3} onClose={this.state.close3} id="Modal3">
<Modal.Header>Inputing Data</Modal.Header>
<Modal.Content>
<InputData onChange={this.InputChange}
onSubmit={this.Submit}
DataInput={[this.state]} />
</Modal.Content>
<Modal.Actions>
<Button negative onClick={this.close3}>No</Button>
<Button positive onClick={()=>this.Submit(this.state)}>Submit</Button>
</Modal.Actions>
</Modal>
<Modal open={this.state.open4} onClose={this.state.close4} id="Modal4">
<Modal.Header>Editing Data</Modal.Header>
<Modal.Content>
<EditData onChange={this.InputChange}
onSubmit={this.Submit}
DataEdit={this.state.edit} />
</Modal.Content>
<Modal.Actions>
<Button negative onClick={this.close4}>No</Button>
<Button positive onClick={()=>this.Submit(this.state)}>Submit</Button>
</Modal.Actions>
</Modal>
</div>
</div>
)
}
}
export default TableComponent
//Table.css//
.TblContainer{
margin: 100px;
}
.AddButton{
display: flex;
justify-content: flex-end;
}
I keep getting the following error when trying to update setState in my SignUp component:
Warning: setState(...): Can only update a mounted or mounting
component. This usually means you called setState() on an unmounted
component. This is a no-op. Please check the code for the SignUp
component.
The error occurs just after a user has signed up, when calling this.setState({ signedUp: true }); inside the open method. Why is this "unmounted" at this particular moment and how can I avoid this issue?
export default class Signup extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: false,
email: "",
password: "",
signedUp: false,
isVerified: false
};
this.open = this.open.bind(this)
}
open() {
if (this.state.signedUp===false) {
this.setState({ signedUp: true });
}
}
close() {
console.log('in close')
}
handleChange = event => {
this.setState({
[event.target.id]: event.target.value
});
}
handleSubmit = async event => {
event.preventDefault();
this.signup(this.state.email, this.state.password).then((user) => {
this.open()
}, (error) => {
alert(error)
});
}
signup(email, password) {
return new Promise(function (resolve, reject) {
firebase.auth().createUserWithEmailAndPassword(email, password).then(function onSuccess(user) {
if (user) {
user.updateProfile({
displayName: (firstName.charAt(0).toUpperCase() + firstName.slice(1) + ' ' + lastName)
}).then(function() {
resolve(user);
}, function(error) {
alert(error)
});
} else {
reject('User not signed up');
}
})
});
}
render() {
return (
<div className="Signup">
<Grid>
<Row>
<Col sm={8} smOffset={2} md={6} mdOffset={3} lg={4} lgOffset={4}>
<h1 className="text-center font-size-l">Sign up</h1>
<Panel>
<form onSubmit={this.handleSubmit}>
<FormGroup controlId="email" bsSize="large">
<ControlLabel>Email</ControlLabel>
<FormControl
type="email"
placeholder="you#company.com"
value={this.state.email}
onChange={this.handleChange}
/>
</FormGroup>
<FormGroup controlId="password" bsSize="large">
<ControlLabel>Password</ControlLabel>
<FormControl
value={this.state.password}
placeholder="Enter a secure password"
onChange={this.handleChange}
type="password"
/>
</FormGroup>
<LoaderButton
block
className="btn-primary"
bsSize="large"
type="submit"
isLoading={this.state.isLoading}
text="Next"
loadingText="Signing up…"
/>
</form>
</Panel>
</Col>
</Row>
</Grid>
<Modal show={this.state.signedUp} onHide={this.close} >
<Modal.Body>
<p>Check your inbox for further instructions.</p>
<LoaderButton
className="btn-primary"
bsSize="large"
type="submit"
text="Resend email"
/>
</Modal.Body>
</Modal>
</div>
);
}
}