React Component Re-Renders when updating input using React Hooks - javascript

I'm working on a React Project. I'm building a form with about 5 fields in it. I've used React Hooks to manage the state of the updates however when I enter in an input into the field. I can see the component re-render each time I enter a key stroke. the re-render is causing issues because it sets a state of a form field back to empty. Any help would be greatly appreciated!
Thanks,
Link to a gif of the re-render on keystroke can be found here: https://gph.is/g/ZxDqzmN
Link to clearing the form field: https://gph.is/g/4LjmDpd
import React, { useState } from "react";
import styled from "styled-components";
import {
Button,
CardContent,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
Card as MuiCard,
Paper as MuiPaper,
TextField,
} from "#material-ui/core";
import { spacing } from "#material-ui/system";
export default function EmployeeFormDialog() {
const [open, setDialog] = useState(null);
const [carName, setCarName] = useState([""]);
const onSubmit = (data, event) => {
event.preventDefault();
console.log(data);
setDialog(false);
};
console.log("re-render");
const Card = styled(MuiCard)(spacing);
const Paper = styled(MuiPaper)(spacing);
return (
<Card mb={6}>
<CardContent>
<Paper mt={4}>
<div>
<Button variant="contained" color="primary" onClick={() => setDialog(true)}>
Add New Cars
</Button>
<Dialog open={open} aria-labelledby="form-dialog-title" disableEnforceFocus="true">
<form onSubmit={onSubmit}>
<DialogTitle id="form-dialog-title">Add New Car</DialogTitle>
<DialogContent>
<DialogContentText>To add new car</DialogContentText>
<TextField
onChange={(e) => setCarName(e.target.value)}
defaultValue={carName}
name="carName"
margin="dense"
id="carName"
label="Car Name"
type="text"
fullWidth
/>
<TextField
autoFocus
name="carYear"
margin="dense"
id="carYear"
label="Car Year"
type="text"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button type="button" onClick={() => setDialog(false)} color="primary">
Cancel
</Button>
<Button type="submit" color="primary">
Add Car
</Button>
</DialogActions>
</form>
</Dialog>
</div>
</Paper>
</CardContent>
</Card>
);
}

Related

ReactJS: Make Material UI Dialog Box Pop Up Full Screen

When I click on a button, I have a Material UI dialog box pop up successfully (yay!). Now I just want it to be full screen rather than only a small portion of the screen. I am trying to follow along in the Material UI API for the dialog box, but my box is not appearing full screen. Is there some sort of disconnect that I am missing here? Thanks a lot in advance (sorry if this is a noob question).
import React from 'react';
import { makeStyles } from '#material-ui/styles';
import Button from '#material-ui/core/Button';
import TextField from '#material-ui/core/TextField';
import Dialog from '#material-ui/core/Dialog';
import DialogActions from '#material-ui/core/DialogActions';
import DialogContent from '#material-ui/core/DialogContent';
import DialogContentText from '#material-ui/core/DialogContentText';
import DialogTitle from '#material-ui/core/DialogTitle';
import PhotoScrolling from './PhotoScrolling';
/* const useStyles = makeStyles({
imageSlider: {
backgroundColor: 'yellow',
color: 'black',
width: 400,
},
}); */
export default function FormDialog() {
// const classes = useStyles();
const [open, setOpen] = React.useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
<Button variant="outlined" color="primary" onClick={handleClickOpen}>
Open form dialog
</Button>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title"
fullScreen={true}
fullWidth={true}
>Section Title</DialogTitle>
<PhotoScrolling></PhotoScrolling>
<DialogActions>
<Button onClick={handleClose} color="primary">
Close
</Button>
</DialogActions>
</Dialog>
</div>
);
}
Try calling fullscreen={fullscreen} inside <Dialog fullscreen={fullscreen}/> it will work fine.
You are making mistake by calling it inside <DialogTitle/>.
Hope this will work.
return
(
<div>
<Button variant="outlined" color="primary" onClick={handleClickOpen}>
Open form dialog
</Button>
<Dialog
open={open}
onClose={handleClose}
fullScreen={true}//Here you need to add the function
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title"
fullWidth={true}
>Section Title</DialogTitle>
<PhotoScrolling></PhotoScrolling>
<DialogActions>
<Button onClick={handleClose} color="primary">
Close
</Button>
</DialogActions>
</Dialog>
</div>
)

React: How to extract values from Modals?

I have a Chakra UI Modal which opens up onClick of a button. I want to be able to extract the values that a user puts into the inputs/radio buttons when they close the Modal. The Modal class and the Modal/Button render is shown below. Since the input and radio buttons are defined within the Modal class, is it possible to get their final values onClose?
Modal.tsx
import React from 'react'
import {
Modal as ChakraModal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
ModalCloseButton,
RadioGroup,
Stack,
Radio,
VStack
} from "#chakra-ui/react"
import Button from './Button'
import Input from './Input'
type Props = { isOpen : boolean } & { onClose : () => void} & { label : string }
const Modal = ({ label, isOpen, onClose, ...rest }: Props) => (
<ChakraModal {...rest} isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>{label}</ModalHeader>
<ModalCloseButton />
<ModalBody>
<VStack spacing={4}>
<RadioGroup>
<Stack direction="row">
<Radio value="1">Annually</Radio>
<Radio value="2">Semi-Annual</Radio>
<Radio value="3">Quarterly</Radio>
<Radio value="4">Monthly</Radio>
</Stack>
</RadioGroup>
<Input
label="Custom Interest rate"
name="Custom Interest rate"
/>
</VStack>
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={onClose}>
Save
</Button>
</ModalFooter>
</ModalContent>
</ChakraModal>
)
export default Modal
Render
<Button onClick={onOpen}> Settings </Button>
<Modal
label="Custom Settings"
isOpen={isOpen}
onClose={onClose}
/>
You should probably send a state as the modal's prop.
const [state, setState] = React.useState();
<Modal
label="Custom Settings"
isOpen={isOpen}
onClose={onClose}
onChange={setState}
/>
To get the type of setState, hover over the variable and you can see the type definition.

How to edit a form when it is loaded with values?

I have a form loaded with values when it is rendered by onClick from a component. I need to edit the current values and perform an update operation.
Following is the sandbox link
https://codesandbox.io/s/material-demo-forked-e9fju?file=/demo.js.
Should I set the state to implement this?
Yes you need to save value in state. And when user click on subscribe fetch that value from state. Here is updated code:
import React from "react";
import Button from "#material-ui/core/Button";
import TextField from "#material-ui/core/TextField";
import Dialog from "#material-ui/core/Dialog";
import DialogActions from "#material-ui/core/DialogActions";
import DialogContent from "#material-ui/core/DialogContent";
import DialogContentText from "#material-ui/core/DialogContentText";
import DialogTitle from "#material-ui/core/DialogTitle";
import Form from "semantic-ui-react";
export default function FormDialog() {
const [open, setOpen] = React.useState(false);
const [value, setValue] = React.useState("Hello");
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
<Button variant="outlined" color="primary" onClick={handleClickOpen}>
Open form dialog
</Button>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">Subscribe</DialogTitle>
<DialogContent>
<DialogContentText>
To subscribe to this website, please enter your email address here.
We will send updates occasionally.
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="name"
label="Application Name"
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="primary">
Cancel
</Button>
<Button onClick={handleClose} color="primary">
Subscribe
</Button>
</DialogActions>
</Dialog>
</div>
);
}
Here is the demo: https://codesandbox.io/s/material-demo-forked-ln0xe?file=/demo.js:0-1824

How can i make this const into class on react.js

import React, { useState, Component } from 'react';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter, Row, Col, CardHeader, CardBody, Card, } from 'reactstrap';
const ModalBuySell = (props) => {
const {
buttonLabel,
className
} = props;
const datas = props;
const [modal, setModal] = useState(false);
const toggle = () => setModal(!modal);
return (
<div>
<Button color="danger" onClick={toggle}>Buy / Sell</Button>
<Modal isOpen={modal} toggle={toggle} className={className}>
<ModalHeader toggle={toggle}>{datas.name} (No. ID {datas.id}) Transaction(s)</ModalHeader>
<ModalBody>
<Row>
<Col>
<b>In-hand Quantity</b>
</Col>
<Col xs="1">
<i className="fa fa-arrow-right"></i>
</Col>
<Col>
{datas.inHand}
</Col>
</Row>
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={toggle}>Cancel</Button>
</ModalFooter>
</Modal>
</div>
);
}
export default ModalBuySell;
I tried to give my button some onChange function but first i need to make this to class, i'm beginner so i just search on the internet but all the solutions makes me use class instead of my code like that.

How can I get this React Bootstrap Modal Working properly?

I have a exercise I am working on/attempting to replicate and I am trying to add a modal button to the file. I have the button and the modal from React Bootstrap, however, I am unable to get the actual modal to show up. I was using the documentation from React-Bootstrap but getting the actual modal to come up is not working, I have tried to import the various modals but to no avail, am I missing something in my code?
import React from 'react';
import { Modal, Form, FormControl, Button, ButtonToolbar, InputGroup } from 'react-bootstrap';
import { connect } from 'react-redux';
import { addItem } from '../actions/itemActions';
function ItemModal(props) {
return (
<div>
<Button
variant="dark"
style={{marginBottom: '2em'}}
>Add Item
</Button>
<Modal
{...props}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered
>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
Add to Shopping List
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Label for="item">Item</Form.Label>
<InputGroup className="mb-3">
<FormControl
type="text"
name="name"
id="item"
aria-label="Add Shopping Item"
aria-describedby="basic-addon2"
/>
<InputGroup.Append>
<Button onClick={props.onHide} variant="outline-dark">Add</Button>
</InputGroup.Append>
</InputGroup>
</Form>
</Modal.Body>
</Modal>
</div>
);
}
function App() {
const [modalShow, setModalShow] = React.useState(false);
return (
<ButtonToolbar>
<Button variant="dark" onClick={() => setModalShow(true)}>
Add Item
</Button>
<ItemModal
show={modalShow}
onHide={() => setModalShow(false)}
/>
</ButtonToolbar>
);
}
export default connect()(ItemModal);
I do have this extra bit of code that I though would function to open the modal but I don't think it works with this version of Bootstrap?
state = {
modal: false,
name: ''
}
toggle = () => {
this.setState({
modal: !this.state.modal
});
};
onChange = (e) => {
this.setState({ [e.target.name]: e.target.value });
}
From your code snippet, I found an issue.
You have 2 component's in a single file, App and ItemModal. From which App component is your base / parent component and ItemModal is your child component.
But you are exporting child compoennt,
export default connect()(ItemModal);
You should export the parent component,
export default connect()(App);

Categories