React-Redux: Data not read during initial render in useState - javascript

I am trying to get a list of data called packages and put it in a table. Added filter and sorting to it.
I get packages from pakageList reducer
Assign to data state
Then add soring and filtering logic and assign data to variable called filteredPackages
Everything seems fine but when the page initially loads the contents of the table is empty i.e, the data state is empty. This happens while adding or deleting a package and render occurs as well.
Once I go back and come to this screen again the data loads. The data is present in the packages which I get from reducers but it does not get assigned to the data state.
Can anyone try checking and let me know what can be done here. Sorry if my code is not good. Thanks in advance.
Skipping code which is not necessary
const PackageScreen = ({ match }) => {
const [ order, setOrder ] = useState('ASC')
const packageList = useSelector(state => state.packageList)
const { loading, error, packages } = packageList
const packageCreate = useSelector(state => state.packageCreate)
const { loading:loadingCreate , error:errorCreate , success: successCreate, package: createdPackage } = packageCreate
const packageDelete = useSelector(state => state.packageDelete)
const { loading:loadingDelete , error:errorDelete , success: successDelete } = packageDelete
const [ data, setData ] = useState([])
useEffect(() => {
dispatch({type: PACKAGE_CREATE_RESET})
if(!userInfo || !userInfo.isAdmin){
navigate('/')
}
setName('')
setMaxDays(0)
setMaxUsers(0)
dispatch(listPackages())
setData(packages)
}, [dispatch, userInfo, successCreate, successDelete, navigate] )
const sorting = (col) => {
if(order === 'ASC'){
const sorted = [...data].sort((a,b) =>
a[col].toString().toLowerCase() > b[col].toString().toLowerCase() ? 1 : -1
)
setData(sorted)
setOrder('DSC')
}
if(order === 'DSC'){
const sorted = [...data].sort((a,b) =>
a[col].toString().toLowerCase() < b[col].toString().toLowerCase() ? 1 : -1
)
setData(sorted)
setOrder('ASC')
}
}
function search(data) {
return data.filter((pack) =>
pack.packageName.toLowerCase().indexOf(q.toLowerCase()) > -1
)
}
const filteredPackages = search(data)
const submitHandler = (e) =>{
e.preventDefault()
dispatch(createPackage({
packageName: name,
maxDaysAllowed : maxDays * 30,
maxUserAllowed : maxUsers
}))
}
const deleteHandler = (id) =>{
if(window.confirm('Are you sure you want to delete?')){
dispatch(deletePackage(id))
}
}
return(
<>
<Link to='/' className='btn btn-dark my-3'>Go Back</Link>
<h1>Add Package</h1>
<Form onSubmit={submitHandler}>
<Row className='my-3' >
<Col>
<Form.Group className="mb-3" controlId='name'>
<FloatingLabel controlId="floatingInput" label="Package Name" className="mb-3">
<Form.Control type="text" placeholder="Package name"
value={name}
onChange = {(e)=> setName(e.target.value)}
/>
</FloatingLabel>
</Form.Group>
</Col>
<Col>
<Form.Group controlId='maxUsers'>
<FloatingLabel controlId="floatingSelect" label="Max. allowed users">
<Form.Control as='select' value={maxUsers}
onChange={(e) => setMaxUsers(e.target.value)}>
{/*<Form.Select aria-label="Floating label select example">*/}
<option>Select number of users</option>
<option value="3">3</option>
<option value="5">5</option>
<option value="10">10</option>
{/*</Form.Select>*/}
</Form.Control>
</FloatingLabel>
</Form.Group>
</Col>
<Col>
<Form.Group controlId='maxDays'>
<FloatingLabel controlId="floatingSelect" label="Package Limit">
<Form.Control as='select' value={maxDays}
onChange={(e) => setMaxDays(e.target.value)}>
{/*<Form.Select aria-label="Floating label select example">*/}
<option>Select Period</option>
<option value="1">1 Month</option>
<option value="3">3 Months</option>
<option value="6">6 Months</option>
<option value="12">1 year</option>
{/*</Form.Select>*/}
</Form.Control>
</FloatingLabel>
</Form.Group>
</Col>
</Row>
<Button type='submit' variant='primary'>
Save
</Button>
</Form>
<h2 className='mt-4'>Package List</h2>
<div className='d-flex'>
<div className='p-2'>
<div className='searchTable'>
<InputGroup className="me-2 my-2">
<InputGroup.Text>Search</InputGroup.Text>
<FormControl aria-label="Search"
value={q} onChange={(e) => setQ(e.target.value)}
/>
</InputGroup>
</div>
</div>
</div>
{ loading ? <Loader />
: error ? <Message variant='danger'>{error}</Message>
: (
<div>
<Table striped bordered hover responsive='md' className='table-sm bg-light' id="table-to-xls">
<thead>
<tr>
<th onClick={() => sorting('packageName')} ><span className='btn'>Package Name</span></th>
<th onClick={() => sorting('maxUserAllowed')} ><span className='btn'>Maximum Users</span></th>
<th onClick={() => sorting('maxDaysAllowed')} ><span className='btn'>Maximum Days</span></th>
<th><span className='btn'>Action</span></th>
</tr>
</thead>
<tbody>
{filteredPackages.map(pack => (
<tr key={pack._id} >
<td>{pack.packageName}</td>
<td>{pack.maxUserAllowed}</td>
<td>{pack.maxDaysAllowed}</td>
<td>
{/*<LinkContainer to={`/admin/product/${product._id}/edit`}>*/}
<Button variant='info' className='btn-sm mx-1' disabled>
<i className='fas fa-edit'></i>
</Button>
{/*</LinkContainer>*/}
<Button variant='danger' className='btn-sm'
onClick={()=> deleteHandler(pack._id)}
>
<i className='fas fa-trash'></i>
</Button>
</td>
</tr>
)) }
</tbody>
</Table>
</div>
)
}
</>
)
}
export default PackageScreen
data and filteredPackage both are empty at initial renders.
I tried the below in useEffect but no luck
useEffect(() => {
dispatch({type: PACKAGE_CREATE_RESET})
if(!userInfo || !userInfo.isAdmin){
navigate('/')
}
setName('')
setMaxDays(0)
setMaxUsers(0)
dispatch(listPackages())
**const fetchData = async()=>{
await setData(packages)
}
fetchData()**
}, [dispatch, userInfo, successCreate, successDelete, navigate] )
Please let me know if you need further details.

Make a const for packages and assign this to your data state
const packages = useSelector(state => state.packageList.packages)
...
const [ data, setData ] = useState(packages)
and write a useEffect that updates your data state when ever your package store value renders
useEffect(()=>{
setData([...packages])
},[packages])

Related

Send the selected option to the backend

I have a select menu (with three options) along with a search bar. All I want is to save the selected option and the searched term and send them to the back-end. Here is my code:
import React, { useState, useEffect } from 'react'
const Table = () => {
const navigate = useNavigate()
const [users, setUsers] = useState([]);
const [currentUsers, setCurrentUsers] = useState([]);
const [search, setSearch] = useState('');
const [column, setColumn] = useState(''); //for saving the selected option
useEffect(async () => {
try {
const response = await getUsers(search);
setUsers(response.data.users);
} catch (error) { }
}, [search]);
return (
<input type='text' placeholder='search..' onChange={(e) => setSearch(e.target.value)} value={search} />
<select aria-label=".form-select-sm example">
<option selected value="1">all</option>
<option value="2">name</option>
<option value="3">phone</option>
</select>
<table className='w-full border-separate rounded-md'>
<thead>
<tr className='bg-text-secondary text-white shadow-sm text-center'>
<th className='p-2'>name</th>
<th className='p-2'>phone</th>
</tr>
</thead>
<tbody>
{currentUsers.map((item, index) =>
<tr key={item.id} className={index % 2 === 0 ? 'bg-white shadow-sm text-center' : 'bg-text bg-opacity-5 shadow-sm text-center'}>
<td className='text-text text-sm p-2'>{item.name}</td>
<td className='text-text text-sm p-2'>{item.phone}</td>
</tr>
)}
</tbody>
</table>
)
}
I have been successful in receiving the search term in the back-end, but I don't know how to apply this on the selected option as well. I tried adding onClick() and onChange() on each option and save the state, but I wasn't successful. How can I do this?
Your onChange should be on the select tag. Here is what I did.
import React, { useState, useEffect } from "react";
const Table = () => {
const navigate = useNavigate()
const [users, setUsers] = useState([]);
const [currentUsers, setCurrentUsers] = useState([]);
const [search, setSearch] = useState("");
const [column, setColumn] = useState(""); //for saving the selected option
useEffect(async () => {
try {
const response = await getUsers(search);
setUsers(response.data.users);
} catch (error) { }
}, [search]);
return (
<>
<input
type="text"
placeholder="search.."
onChange={(e) => setSearch(e.target.value)}
value={search}
/>
// added here
<select
aria-label=".form-select-sm example"
onChange={(e) => {
setColumn(e.target.value);
console.log(e.target.value);
}}
>
<option selected value="1">
all
</option>
<option value="2">name</option>
<option value="3">phone</option>
</select>
<table className="w-full border-separate rounded-md">
<thead>
<tr className="bg-text-secondary text-white shadow-sm text-center">
<th className="p-2">name</th>
<th className="p-2">phone</th>
</tr>
</thead>
<tbody>
{currentUsers.map((item, index) => (
<tr
key={item.id}
className={
index % 2 === 0
? "bg-white shadow-sm text-center"
: "bg-text bg-opacity-5 shadow-sm text-center"
}
>
<td className="text-text text-sm p-2">{item.name}</td>
<td className="text-text text-sm p-2">{item.phone}</td>
</tr>
))}
</tbody>
</table>
</>
);
};

How do I display data from my json file that match my filters

I'm creating a multi steps form in React and I want a page (Filters.jsx) in my form, that returns me all the menus name (contained in data.json) that matches my filters ( beaf, chicken, vegetables), but I don't kow how to do that.
import React from "react";
export default function Filter() {
return (
<div className="flex flex-col">
<div className=" w-full mx-2 flex-1">
<div className="font-bold h-6 mt-3 text-gray-600 leading-8 uppercase ">
{" "}
Norms
</div>
<tbody className="bg-white my-2 p-1 flex borer border-gray-200 rounded text-gray-500">
<tr>
<td className="font-bold h-8 mt-5 leading-8 uppercase ">
<td>
<input type="checkbox" value="beaf" className="w-8 h-3" /> beaf
</td>
<td>
<input type="checkbox" value="chicken" className="w-8 h-3" />
chicken
</td>
<td>
<input type="checkbox" value="vegetables" className="w-8 h-3" />
vegetables
</td>
</td>
</tr>
</tbody>
</div>
</div>
);
}
Here is the link of my sandbox ( browse /menu/form to see the form): https://codesandbox.io/s/unruffled-river-ktoic8?
What I tried:
export default function Filters() {
//Filters events
const ref = [
{ name: "beaf" },
{ name: "chicken" },
{ name: "vegetables" }
]
const [norms, setNorms] = useState([]);
useEffect(() => {
setNorms(ref);
}, []);
const handleChange = (e) => {
const { name, checked } = e.target;
let tempR = norms.map((r) =>
r.name === name ? { ...r, isChecked: checked } : r
);
setNorms(tempR);
}
return (
<div>
<form className="form w-100">
{
norms.map((e, index) => (
<div className="form-check" key={index}>
<input
type="checkbox"
className="form-check-input"
name={e.name}
checked={e?.isChecked || false}
onChange={handleChange}
/>
<label className="form-check-label ms-2">{e.name}</label>
</div>
))
}
</form >
</div>
)
I suggest using an object or Map to hold the filter values where the filter name is the key and the checked value is the value.
const [filters, setFilters] = React.useState({});
Create a handler that sets the checked value for a specific input by name.
const changeHandler = (e) => {
const { name, checked } = e.target;
setFilters((filters) => ({
...filters,
[name]: checked
}));
};
Render the inputs and set the checked prop from state.
{["beef", "chicken", "vegetables"].map((name) => (
<td key={name}>
<label>
<input
type="checkbox"
checked={filters[name]}
onChange={changeHandler}
name={name}
className="w-8 h-3"
/>
{name}
</label>
</td>
))}
And then filter/map the data, all inline.
import data from "../../data.json";
...
{data
.filter((item) => {
// get array of enabled filter keys
const filterEntries = Object.entries(filters)
.filter(([, value]) => Boolean(value))
.map(([key]) => key);
// some filter enabled
if (filterEntries.length) {
// check proteins
if (filters.beef || filters.chicken) {
return item.dishes.some((dish) =>
filterEntries.includes(dish.meat)
);
}
// check vegetables
if (filters.vegetables) {
return item.dishes.some((dish) => !!dish.vegetables);
}
}
// no filter enabled, return all elements
return true;
})
.map((item) => (
<tr key={item.id}>
.... map data item properties here ...
</tr>
))}

Hide another component on the click of radio button

I'm very new to React. I'm building a flight booking website. I want to hide the return date form field when the user selects one way trip. I wanted to know what is the best way to go about it.
const TripTypeButton = (props) => {
const [rSelected, setRSelected] = useState(null);
return (
<div>
<ButtonGroup>
<Button color="primary" onClick={() => setRSelected(1)} active={rSelected === 1}>Round Trip</Button>
<Button color="secondary" onClick={() => setRSelected(2)} active={rSelected === 2}>One Way</Button>
</ButtonGroup>
</div>
);
}
const HomePage = (props) =>{
return(
<div>
<div>
<h2> Search for flights</h2>
</div>
<div>
<Form>
<Row form>
<FormGroup>
<TripTypeButton />
</FormGroup>
</Row>
<Row form>
<Col md={3}>
<FormGroup>
<Label>Departure</Label>
<Input type="date" id="departure" name="departure"/>
</FormGroup>
</Col>
<Col md={3}>
<FormGroup>
<Label for="exampleState">Return</Label>
<Input type="date" name="return" id="return"/>
</FormGroup>
</Col>
<Row/>
</Form>
</div>
</div>
);
}
for this situation, you need to keep the state of selected trip type in HomePage component and then based on that state render the Return flight or not!
like below:
const HomePage = (props) => {
const [rSelected, setRSelected] = useState(null);
return (
// some code
// trip type button handler
<TripTypeButton handleSelectedTripType={setRSelected} rSelected={rSelected} />
// the button section of code
{ rSelected !== 1
&& <Col md={3}>
<FormGroup>
<Label for="exampleState">Return</Label>
<Input type="date" name="return" id="return"/>
</FormGroup>
</Col>
}
// rest of jsx code
)
}
and your TripTypeButton would be like below:
const TripTypeButton = ({ handleSelectedTripType, rSelected }) => {
return (
<div>
<ButtonGroup>
<Button color="primary" onClick={() => handleSelectedTripType(1)} active={rSelected === 1}>Round Trip</Button>
<Button color="secondary" onClick={() => handleSelectedTripType(2)} active={rSelected === 2}>One Way</Button>
</ButtonGroup>
</div>
);
}
this is called lifting state up in React! and by that you keep your state in top level components and manage data manipulation by passing required handlers down to the child components by directly props or context!

Changing variable in one file conflicts the data for other file in React JS

I'm having weird problem in React JS. I have two classes named as Notes.js and DataTables.js
I'm using DataTables in Note.js like this
<DataTables
keyField="id"
columns={columns}
url={this.state.url}
useCallBack={true}
onEdit={this.onEdit}
/>
Please Note that DataTables.js is my own custom created DataTable.js not react-datatable.
All the work like fetching data from URL and showing it in tabular form is in DataTables.js file.
Note.js Code:
import React, { Component } from "react";
import { Constant } from "../shared/Constants";
import DataTables from "../shared/DataTables";
import { Modal, Button } from "react-bootstrap";
import BreadCrumb from "../shared/BreadCrumb";
import "../Style.css";
const columns = Constant.notes;
export class Notes extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
url: "notes/get_notes",
showModal: false,
note: [],
};
this.onEdit = this.onEdit.bind(this);
this.onAdd = this.onAdd.bind(this);
this.onUpdate = this.onUpdate.bind(this);
this.saveNote = this.saveNote.bind(this);
}
onUpdate(key, value) {
let noteData = this.state.note;
noteData[key] = value;
this.setState({
note: noteData,
});
}
saveNote(e) {
e.preventDefault();
}
onEdit(n) {
this.setState({
note: n,
showModal: true,
});
}
onAdd() {
this.setState({
note: [],
showModal: true,
});
}
render() {
return (
<>
<Modal
show={this.state.showModal}
aria-labelledby="example-modal-sizes-title-lg"
onHide={() => this.setState({ showModal: false })}
>
<form method="post" onSubmit={this.saveNote}>
<Modal.Header>
<Modal.Title>My Note</Modal.Title>
</Modal.Header>
<Modal.Body>
<div className="row">
<div className="col-sm-12">
<div className="form-group">
<label className="text-muted">Note Title</label>
<input
type="text"
placeholder="Note Title"
className="form-control"
ref="title"
value={this.state.note.title}
onChange={(e) => this.onUpdate("title", e.target.value)}
/>
</div>
<div className="form-group">
<label className="text-muted">Content</label>
<textarea
onChange={(e) => this.onUpdate("content", e.target.value)}
className="form-control"
style={{ height: "250px" }}
placeholder="Content"
>
{this.state.note.content}
</textarea>
</div>
</div>
</div>
</Modal.Body>
<Modal.Footer>
<Button
variant="secondary"
onClick={() => this.setState({ showModal: false })}
>
Close
</Button>
<Button type="submit" variant="primary">
Save Note
</Button>
</Modal.Footer>
</form>
</Modal>
<BreadCrumb
title="My Notes"
useCallBack={true}
onAdd={this.onAdd}
active_link="Notes"
link=""
link_text="Add New"
/>
<div className="row">
<div className="col-sm-12">
<div className="card">
<div className="card-body">
<div className="card-title">Notes</div>
<DataTables
keyField="id"
columns={columns}
url={this.state.url}
useCallBack={true}
onEdit={this.onEdit}
/>
</div>
</div>
</div>
</div>
</>
);
}
}
export default Notes;
I'm having Problem in Note.js on onUpdate function
onUpdate(key, value) {
let noteData = this.state.note;
noteData[key] = value;
this.setState({
note: noteData,
});
}
Problem: When I update a field in Modal as you can see in my code, then my Table in DataTable.js automatically gets updated, I'don't why :/
Here is DataTables.js function where I'm sending data to onEdit function
const TableData = () => {
return (
<tbody>
{tableData.length === 0 ?
<tr>
<td className="text-center" colSpan="5"><strong>No Data Found</strong></td>
</tr>
:
tableData.map((tData) => (
<tr key={tData[this.props.keyField]}>
{this.props.columns.map((item, index) => (
<td key={index} className="table-content">
{index === 0 ?
[(useCallback === true ? <span key={"sub_"+index} className="link" onClick={() => this.props.onEdit(tData)}>{tData[item.dataField]}</span> :
<Link
to={
this.props.edit_link +
"/" +
tData[this.props.edit_key_first] + (this.props.edit_key_second ? "/" +
tData[this.props.edit_key_second] : '')
}
>
{tData[item.dataField]}
</Link>
)]
: (
tData[item.dataField]
)}
</td>
))}
</tr>
))}
</tbody>
);
};
Please check gif image below so you can understand it :P
You have an onChange function that is updating the content
onChange={(e) => this.onUpdate("content", e.target.value)}
If you don't want to change the content while typing then you will have to remove this.

React not closing dialog box

Im using materialUI to click a menu item that then opens a dialog box(child component) however after the dialogbox opens it wont seem to close and wont update the data for noticeModal. There are not any errors being thrown and i belive it has to do with using useEffect to setNoticeModal(props.open) for the initial state. Ive tried removing the useEffect() and throwing props.open into the default useDate() for the noticeModal however upon doing that then my dialogbox wont open anymore at all. What am i over looking here?
holidaySettings.js
...
const [dialogOpen, setDialogOpen] = React.useState(false);
const handleDialogOpen = (dataElement) => {
setDialogData(dataElement);
setDialogOpen(true);
setOpen(false);
}
...
<ClickAwayListener onClickAway={handleClose}>
<MenuList autoFocusItem={open} id="menu-list-grow" onKeyDown={handleListKeyDown}>
<MenuItem onClick={handleDialogOpen}>Add Holiday</MenuItem>
</MenuList>
</ClickAwayListener>
...
<div className="card-body">
<div className="row">
<div className="text-left col-12">
<Styles>
<Table columns={columns} data={data} />
<HolidayDialog open={dialogOpen} onClose={handleDialogClose} data={dialogData}/>
</Styles>
</div>
</div>
</div>
...
holidayDialog.js
const HolidayDialog = (props) => {
const [noticeModal, setNoticeModal] = useState(false);
const [selectedDate, setSelectedDate] = useState(new Date());
const [holidayData, setHolidayData] = useState(props.data);
useEffect(() => {
setNoticeModal(props.open)
});
const handleDateChange = (date) => {
setSelectedDate(date);
};
const handleClose = () => {
setNoticeModal(false);
console.log(noticeModal);
};
const handleChange = (e) => {
const { name, checked } = e.target;
setHolidayData((prevState) => ({ ...prevState, [name]: checked }));
};
const updateValues = (e) => {
const { name, value } = e.target;
setHolidayData((prevState) => ({ ...prevState, [name]: value }));
}
return (
<Dialog
open={noticeModal}
TransitionComponent={Transition}
keepMounted
onClose={handleClose}
aria-labelledby="notice-modal-slide-title"
aria-describedby="notice-modal-slide-description"
>
<DialogTitle id="customized-dialog-title" onClose={handleClose}>
{holidayData.HolidayName ? holidayData.HolidayName : 'Create New Holiday'}
</DialogTitle>
<DialogContent dividers>
<form noValidate autoComplete="off">
<div className="row">
<div className="col">
<TextField required name="HolidayName" id="outlined-basic" label="Holiday Name" variant="outlined" onChange={updateValues} value={holidayData.HolidayName || ''}/>
</div>
<div className="col">
<TextField id="outlined-basic" name="Branch" label="Branch" variant="outlined" onChange={updateValues} value={holidayData.Branch || 'ALL'}/>
</div>
</div>
<div className="row mt-3">
<div className="col">
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
disableToolbar
variant="inline"
format="MM/dd/yyyy"
margin="normal"
id="date-picker-inline"
label="Date picker inline"
value={selectedDate}
onChange={handleDateChange}
KeyboardButtonProps={{
'aria-label': 'change date',
}}
/>
</MuiPickersUtilsProvider>
</div>
<div className="col">
<TextField id="outlined-basic" name="Hours" label="Hours" variant="outlined" onChange={updateValues} value={holidayData.Hours || 'Closed'}/>
</div>
</div>
<div className="row mt-3">
<div className="col d-flex flex-column">
<FormControlLabel
control={
<Checkbox
checked={holidayData.Web || false}
value={holidayData.Web}
onChange={handleChange}
name="Web"
color="primary"
/>
}
label="Show on Web?"
/>
<FormControlLabel
control={
<Checkbox
checked={holidayData.CoOp || false}
value={holidayData.CoOp}
onChange={handleChange}
name="CoOp"
color="primary"
/>
}
label="CoOp Holiday?"
/>
</div>
<div className="col d-flex flex-column">
<FormControlLabel
control={
<Checkbox
checked={holidayData.Phone || false}
value={holidayData.Phone}
onChange={handleChange}
name="Phone"
color="primary"
/>
}
label="Use in IVR?"
/>
<FormControlLabel
control={
<Checkbox
checked={holidayData.Active || true}
value={holidayData.Active}
onChange={handleChange}
disabled
name="Active"
color="primary"
/>
}
label="Active"
/>
</div>
</div>
</form>
</DialogContent>
<DialogActions>
<Button autoFocus onClick={handleClose} color="default">
Cancel
</Button>
<Button autoFocus onClick={handleClose} color="primary">
Create Holiday
</Button>
</DialogActions>
</Dialog>
)
}
export default HolidayDialog;
Could you try this?
I am assuming props.onClose is making dialogOpen to false on parent(holidaySettings)
const handleClose = () => {
props.onClose()
};
If props.onClose is not making dialogOpen to false on parent(holidaySettings).You can add close attribute which sets dialogOpen to false.
<HolidayDialog open={dialogOpen} close={()=>setDialogOpen(false);} onClose={handleDialogClose} data={dialogData}/>
const handleClose = () => {
props.close()
};
And passing props.open to Dialog
<Dialog
open={props.open}
/>
You are not providing any dependency to useEffect so it runs on every re-render. In your useEffect you are toggling the modal and hence the issue.
useEffect(() => {
setNoticeModal(props.open)
});//<---- issue - missing dependency
Solution - pass dependency as props.open. This makes the useEffect to run only when props.open is changed.
useEffect(() => {
setNoticeModal(props.open)
}, [props.open]); //<----- props.open
Inside the useEffect, you are resetting the noticeModal value to props.open which i believe is true?
I believe what you are trying to do is set the initial value of noticeModal.
Try changing to the code below and remove the useEffect
const [noticeModal, setNoticeModal] = useState(props.open);

Categories

Resources