stacked dynamic inputs - reactjs - reactjs

I have an input and a select starting when placing any value in the case of the input, it begins to generate dynamic statements and in the case of the input, dynamic inputs are generated but in decrement, everything works fine, I only need that the dynamic inputs that begin to appear are show one by one and not all piled up as I show in the picture.
problem image
how do i want it to be
import React, { useState } from "react";
//input dynamic
import Row from "./Row2";
let initialState = {
first: null,
arraySelect: []
};
function Pruebas(props) {
/*input dynamic */
const [rows, setRows] = useState([]);
const [initialeRow, setInitialRow] = useState({ nombre: "" });
const handleOnChange = (index, value) => {
const copy = rows.map((e, i) => {
if (i === index) {
e.nombre = value;
}
return e;
});
setRows([...copy]);
};
const handleOnAdd = () => {
if (initialeRow.nombre >= 1) {
setInitialRow({ nombre: initialeRow.nombre - 1 });
setRows([...rows, initialeRow]);
}
};
/////////////////////////////////////////////////////
const [input_multi, setInput_multi] = useState();
const [arraySelect, setarraySelect] = useState(initialState.arraySelect);
const [numberIni, setnumberIni] = useState(initialState.first);
const getArray = (value) => {
let arr = [];
{
let reco = Math.round(numberIni - parseInt(value));
console.log(reco);
if (parseInt(value) == numberIni) {
return false;
}
Array(reco)
.fill(1)
.map((value2, key) => {
arr.push(parseInt(value) + parseInt(key + 1));
});
}
return arr;
};
const setSelect = (value) => {
let isArray = getArray(value);
if (isArray) {
setarraySelect([...arraySelect, isArray]);
}
//input dynamyc
if (initialeRow.nombre >= 1) {
setInitialRow({ nombre: initialeRow.nombre - 1 });
setRows([...rows, initialeRow]);
}
};
//input dynamic
const handleInput_division = (event) => {
setInitialRow({ nombre: event.target.value });
};
const handleSubmit = (event) => {
event.preventDefault();
setnumberIni(event.target.numberIni.value);
};
const resetForm = () => {
setnumberIni(null);
setarraySelect([]);
};
return (
<div>
<form onSubmit={handleSubmit}>
<div class="row">
<label>PHASES</label>
<div class="col-sm-6">
<h6>enter a number</h6>
<div class="input-group ">
<input
type="number"
name="numberIni"
placeholder="0"
class="form-control"
value={input_multi}
onChange={(event) => setInput_multi(event.target.value)}
/>
<br />
<button type="submit" className="btn btn-success"> <i class="far fa-save"></i></button>
<br />
<div class="col-sm-6">
<h6>2 - # input dynamic</h6>
<div class="input-group ">
<select name='numberIni2' class='form-control' onChange={handleInput_division}>
<option value='no' selected>
Seleccione </option>
<option value='2'> 2</option>
<option value='3'>3
</option>
</select>
<br/>
</div>
</div>
</div>
</div>
</div>
</form>
<br />
<div class="col-sm-12 btn btn-primary">
<b>PHASES</b>
</div>
<br /> <br />
<div class="row">
<div class="col-sm-12">
{numberIni && (
<div class="col-sm-12">
<label>
<font size="2">
1° PHASES <br />
select a number : {" "}
</font>
</label>
<select onChange={(e) => setSelect(e.target.value)} name="" id="">
<option value="seleccione">Seleccione</option>
{Array(parseInt(numberIni))
.fill(1)
.map((value, key) => {
return <option value={key + 1}>{key + 1} equipment</option>;
})}
</select>
<label>
<font size="2"> equipment </font>{" "}
</label>
{Array(parseInt(numberIni))
.fill(1)
.map((value, key2) => {
return (
<div>
{arraySelect[key2] && (
<>
<label>
<font size="2">
2° select another number <br />
classify: {" "}
</font>{" "}
</label>
<select
onChange={(e) => setSelect(e.target.value)}
name=""
id=""
>
<option value="seleccione">Seleccione</option>
{arraySelect[key2].map((value, key3) => {
return (
<option value={arraySelect[key2][key3]}>
{arraySelect[key2][key3]} equipment
</option>
);
})}
</select>
{rows.map((e, index) => (
<Row
nombre={e.nombre}
index={index}
onChange={(index, value) => handleOnChange(index, value)}
key={index}
/>
))}
</>
)}
</div>
);
})}
</div>
)}
</div>
</div>
{numberIni && (
<input
onClick={() => resetForm()}
type="button"
className="btn btn-danger"
value="restart phase"
/>
)}
</div>
);
}
export default Pruebas;
//Row2
const Row = (props) => {
const { onChange, onRemove, nombre, index } = props;
console.log(props);
return (
<div>
<input
disabled
value={nombre}
onChange={(e) => onChange(index, e.target.value)}
placeholder="Decrementar"
/>
</div>
);
};
export default Row;

Related

Edit Data in Parent from Child

Apparently I'm not doing this right, but I'm trying to mutate a map in the parent component from a child component in React 18.2. The parent contains a modal which opens a form. The user then inputs their mutate option (delete/add) and subsequent data from there. I've been going through other questions trying to find an answer for why it's not working as intended, but I can't seem to find much info. Would appreciate any help. This is what I currently have:
Parent.Js
const ParentComponent = ({show, onCloseModalButton}) => {
const resorts = new Map()
resorts.set("Keystone", [39.6069742, -105.97011])
resorts.set("Breckenridge", [39.4808, -106.0676])
resorts.set("Vail", [39.6061, -106.3550])
resorts.set("Crested Butte", [38.8991, -106.9658])
resorts.set("Winter Park", [39.8841, -105.7627])
resorts.set("Copper Mountain", [39.5022, -106.1497])
const [formOption, setFormOption] = React.useState("")
const [formData, setFormData] = React.useState({
resortName: "",
longitude: Number,
latitude: Number,
})
const handleOptionChange = e => {
setFormOption(e.target.value)
}
const handleFormDataChange = e => {
setFormData({
...formData,
[e.target.name]: e.target.value,
})
}
const submitForm = e => {
e.preventDefault()
if (formOption === "Add") {
resorts.set(formData.resortName, [formData.latitude, formData.longitude])
}
if (formOption === "Delete") {
resorts.delete(formData.resortName)
}
}
return (
<div>
<Modal show={show} onCloseModalButton={onCloseModalButton} resorts={resorts} submitForm={submitForm} handleOptionChange={handleOptionChange} handleFormChange={handleFormDataChange} option={formOption} form={formData} />
</div>
)
}
export default ParentComponent;
Modal.js
const Modal = ({show, onCloseModalButton, resorts, submitForm, handleOptionChange, handleFormChange, option, form}) => {
if (!show) {
return null
}
return ReactDOM.createPortal (
<div className='modal-bg'>
<div className='modal'>
<form onSubmit={submitForm}>
<label>Modify:
<select
name="option"
value={option}
onChange={handleOptionChange}
>
<option value="" disabled={true}>-- Choose an Option --</option>
<option value="Add">Add</option>
<option value="Delete">Delete</option>
</select>
</label>
{option === "" ? null :
option === "Add" ?
<div>
<label>Resort Name
<input
type="text"
name="resortName"
value={form.resortName}
onChange={handleFormChange}
/>
</label>
<br></br>
<label>Longitude
<input
type="number"
name="longitude"
value={form.longitude}
onChange={handleFormChange}
/>
</label>
<br></br>
<label>Latitude
<input
type="number"
name="latitude"
value={form.latitude}
onChange={handleFormChange}
/>
</label>
<button type='submit'>Submit</button>
</div> :
<div>
<label>Delete
<select
name="delete"
value={form.resortName}
onChange={handleFormChange}
>
{[...resorts.keys()].map((item)=> {
return <option key={item} value={item}>{item}</option>
})}
</select>
</label>
<button type='submit'>Submit</button>
</div>
}
</form>
<button onClick={onCloseModalButton}>Close Modal</button>
</div>
</div>
, document.body
)
}
export default Modal;

Filter fetch data react

Why filter by search work but by drop-down list not?
I don't know why this is so, maybe someone sees some error.
I would like to filter tags using checkboxes. It was hard for me to find a tutorial on the internet, I was able to find filtering by searching. It turned out that everything was set up successfully, then I wanted to set filtering by list, but here I have a problem. I don't know why the list search doesn't work - even though it seems to work on the console.
demo here:
https://codesandbox.io/s/adoring-wu-rt4wd?file=/src/styles.css
const [filterParam, setFilterParam] = useState(['All'])
const [q, setQ] = useState('')
const [searchParam] = useState(['tags'])
function search(data) {
return data.filter((item) => {
if (item.tags == filterParam) {
return searchParam.some((newItem) => {
return (
item[newItem].toString().toLowerCase().indexOf(q.toLowerCase()) > -1
)
})
} else if (filterParam == 'All') {
return searchParam.some((newItem) => {
return (
item[newItem].toString().toLowerCase().indexOf(q.toLowerCase()) > -1
)
})
}
})
}
return (
<>
<div>
<label htmlFor='search-form'>
<input
type='search'
name='search-form'
id='search-form'
className='search-input'
placeholder='Search for...'
value={q}
onChange={(e) => setQ(e.target.value)}
/>
<span className='sr-only'>Search countries here</span>
</label>
</div>
<div className='select'>
<select
onChange={(e) => {
setFilterParam(e.target.value)
// console.log(setFilterParam(e.target.value.toString()))
console.log(e.target.value.toString())
}}
aria-label='Filter Countries By Region'
>
<option value='All'>All</option>
<option value='accessibility'>accessibility</option>
<option value='javascript'>javascript</option>
<option value='css'>css</option>
<option value='advanced'>advanced</option>
<option value='svg'>svg</option>
</select>
</div>
<section className={styles.main}>
{search(data).map((item) => (
<div className={styles.card}>
<div>
<div className={styles.card__first}>
<div className={styles.card__name}>
<FaTwitter className={styles.card__icon} />
<span className={styles.card__author}>{item.authorId}</span>
</div>
<div className={styles.card__price}>
<p>{item.price}</p>
</div>
</div>
<div className={styles.card__title}>
<h1>{item.title}</h1>
</div>
<div>
<p className={styles.card__desc}>{item.description}</p>
</div>
</div>
<div className={styles.card__tags}>
{item.tags.map((t) => {
return (
<div className={styles.card__tag}>
<p>{t}</p>
</div>
)
})}
</div>
</div>
))}
</section>
</>
)
}
export default Page
You have to change a lot of things, you can try this example
import "./styles.css";
import { useState, useEffect } from "react";
import styles from "./App.module.css";
export default function App() {
const [data, setData] = useState([]);
const [filterParam, setFilterParam] = useState("All");
const [q, setQ] = useState("");
const [searchParam, setSearchParam] = useState([]);
const getData = () => {
fetch("data.json", {
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
})
.then(function (response) {
console.log(response);
return response.json();
})
.then(function (myJson) {
console.log(myJson);
setData(myJson);
});
};
useEffect(() => {
getData();
}, []);
function search(data) {
return data.filter(
(item) =>
(filterParam === "All" || item.tags.includes(filterParam)) &&
(searchParam.length === 0 ||
(searchParam.every((tag) => item.tags.includes(tag)) &&
JSON.stringify(item).toLowerCase().indexOf(q.toLowerCase()) > -1))
);
}
const inputChangedHandler = (event) => {
const value = event.target.value;
const index = searchParam.indexOf(value);
if (index > -1) {
const updatedParam = [...searchParam];
updatedParam.splice(index, 1);
setSearchParam(updatedParam);
} else {
setSearchParam([...searchParam, event.target.value]);
}
};
return (
<>
<div>
<label htmlFor="search-form">
<input
type="search"
name="search-form"
id="search-form"
className="search-input"
placeholder="Search for..."
value={q}
onChange={(e) => setQ(e.target.value)}
/>
<span className="sr-only">Search countries here</span>
</label>
</div>
<div className="select">
<select
onChange={(e) => {
setFilterParam(e.target.value);
// console.log(setFilterParam(e.target.value.toString()))
console.log(e.target.value.toString());
}}
aria-label="Filter Countries By Region"
>
<option value="All">All</option>
<option value="accessibility">accessibility</option>
<option value="javascript">javascript</option>
<option value="css">css</option>
<option value="advanced">advanced</option>
<option value="svg">svg</option>
</select>
</div>
<div>
<input
type="checkbox"
id="topping"
name="advanced"
value="advanced"
onChange={inputChangedHandler}
/>
advanced
</div>
<div>
<input
type="checkbox"
id="topping"
name="javascript"
value="javascript"
onChange={inputChangedHandler}
/>
javascript
</div>
<div>
<input
type="checkbox"
id="topping"
name="fundamentals"
value="fundamentals"
onChange={inputChangedHandler}
/>
fundamentals
</div>
<div>
<input
type="checkbox"
id="topping"
name="css"
value="css"
onChange={inputChangedHandler}
/>
css
</div>
<div>
<input
type="checkbox"
id="topping"
name="svg"
value="svg"
onChange={inputChangedHandler}
/>
svg
</div>
<div>
<input
type="checkbox"
id="topping"
name="accessibility"
value="accessibility"
onChange={inputChangedHandler}
/>
accessibility
</div>
<section className={styles.main}>
{search(data).map((item) => (
<div className={styles.card}>
<div>
<div className={styles.card__first}>
<div className={styles.card__name}>
<p className={styles.card__icon}>ICON</p>
<span className={styles.card__author}>{item.authorId}</span>
</div>
<div className={styles.card__price}>
<p>{item.price}</p>
</div>
</div>
<div className={styles.card__title}>
<h1>{item.title}</h1>
</div>
<div>
<p className={styles.card__desc}>{item.description}</p>
</div>
</div>
<div className={styles.card__tags}>
{item.tags.map((t) => {
return (
<div className={styles.card__tag}>
<p>{t}</p>
</div>
);
})}
</div>
</div>
))}
</section>
{/* <Margins>
<Header data={data} />
<Main data={data} />
</Margins> */}
</>
);
}
enter link description here

How do i limit the list of data being rendered for a particular list in react js

I'm trying to create an app that when the user clicks on create button a survey question with four answers gets created. The goal is that in a single list the user can maximum add up to 4 questions and a minimum of 1 question. So when the user tries to add another question after the 4th question a new survey list should be created. So one survey list can contain a maximum of four questions.
//Survey.js
import React, { useState, useEffect } from "react";
import { Fragment } from "react";
import "./Survey.css";
import CreateSurvey from "../modals/CreateSurvey";
import Card from "../card/Card";
const Survey = () => {
const [modal, setModal] = useState(false);
const [surveyList, setSurveyList] = useState([]);
useEffect(() => {
let arr = localStorage.getItem("surveyList");
if (arr) {
let obj = JSON.parse(arr);
setSurveyList(obj);
}
}, []);
// const surveyListArray = [];
// while (surveyList.length > 0) {
// surveyListArray.push(surveyList.splice(0, 3));
// }
const deleteSurvey = (index) => {
let tempList = surveyList;
tempList.splice(index, 1);
localStorage.setItem("surveyList", JSON.stringify(tempList));
setSurveyList(tempList);
window.location.reload();
};
const toggle = () => {
setModal(!modal);
};
const updateListArray = (obj, index) => {
let tempList = surveyList;
tempList[index] = obj;
localStorage.setItem("surveyList", JSON.stringify(tempList));
setSurveyList(tempList);
window.location.reload();
};
const saveSurvey = (surveyObj) => {
let tempList = surveyList;
tempList.push(surveyObj);
localStorage.setItem("surveyList", JSON.stringify(tempList));
setSurveyList(surveyList);
setModal(false);
};
return (
<Fragment>
<div className="header text-center">
<h5>Survey</h5>
<button className="btn btn-primary" onClick={() => setModal(true)}>
Create Survey
</button>
</div>
<div className="survey-container">
{surveyList &&
surveyList.map((obj, index) => (
<Card
surveyObj={obj}
index={index}
deleteSurvey={deleteSurvey}
updateListArray={updateListArray}
>
<input type="radio" name="answerOne" />
</Card>
))}
</div>
<CreateSurvey toggle={toggle} modal={modal} save={saveSurvey} />
</Fragment>
);
};
export default Survey;
//Card.js
import React, { useState } from "react";
import "./Card.css";
import EditSurvey from "../modals/EditSurvey";
const Card = ({ surveyObj, deleteSurvey, index, updateListArray }) => {
const [modal, setModal] = useState(false);
const toggle = () => {
setModal(!modal);
};
const updateSurvey = (obj) => {
updateListArray(obj, index);
};
const deleteHandler = () => {
deleteSurvey(index);
};
return (
<div>
<div className="card-wrapper mr-5">
<div className="card-top"></div>
<div className="survey-holder">
<span className="card-headers">{surveyObj.name}</span>
<span className="check">
<input type="radio" className="radio" />
<p className="answer"> {surveyObj.answerOne}</p>
</span>
<span className="check">
<input type="radio" className="radio" />
<p className="answer"> {surveyObj.answerTwo}</p>
</span>
<span className="check">
<input type="radio" className="radio" />
<p className="answer"> {surveyObj.answerThree}</p>
</span>
<span className="check">
<input type="radio" className="radio" />
<p className="answer"> {surveyObj.answerFour}</p>
</span>
<div className="icons">
<i className="far fa-edit edit" onClick={() => setModal(true)}></i>
<i className="fas fa-trash-alt delete" onClick={deleteHandler}></i>
</div>
</div>
<EditSurvey
modal={modal}
toggle={toggle}
updateSurvey={updateSurvey}
surveyObj={surveyObj}
/>
</div>
</div>
);
};
export default Card;
//CreateSurvey.js
import React, { useState } from "react";
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
import { Fragment } from "react";
const CreateSurvey = ({ modal, toggle, save }) => {
const [question, setQuestion] = useState("");
const [answerOne, setAnswerOne] = useState("");
const [answerTwo, setAnswerTwo] = useState("");
const [answerThree, setAnswerThree] = useState("");
const [answerFour, setAnswerFour] = useState("");
const changeHandler = (e) => {
const { name, value } = e.target;
if (name === "question") {
setQuestion(value);
} else if (name === "answerOne") {
setAnswerOne(value);
} else if (name === "answerTwo") {
setAnswerTwo(value);
} else if (name === "answerThree") {
setAnswerThree(value);
} else {
setAnswerFour(value);
}
};
const saveHandler = (e) => {
e.preventDefault();
let surveyObj = {};
surveyObj["name"] = question;
surveyObj["answerOne"] = answerOne;
surveyObj["answerTwo"] = answerTwo;
surveyObj["answerThree"] = answerThree;
surveyObj["answerFour"] = answerFour;
save(surveyObj);
};
return (
<Fragment>
<Modal isOpen={modal} toggle={toggle}>
<ModalHeader toggle={toggle}>Create a Survey Question</ModalHeader>
<ModalBody>
<form>
<div>
<div className="form-group">
<label>Survey Questions</label>
<input
type="text"
className="form-control"
value={question}
name="question"
onChange={changeHandler}
/>
</div>
</div>
<div className="mt-2">
<label>Survey Answers</label>
<div className="form-group">
<label>Answer 1</label>
<input
type="text"
className="form-control mt-2 mb-2"
value={answerOne}
name="answerOne"
onChange={changeHandler}
/>
</div>
<div className="form-group">
<label>Answer 2</label>
<input
type="text"
className="form-control mt-2 mb-2"
value={answerTwo}
name="answerTwo"
onChange={changeHandler}
/>
</div>
<div className="form-group">
<label>Answer 3</label>
<input
type="text"
className="form-control mt-2 mb-2"
value={answerThree}
name="answerThree"
onChange={changeHandler}
/>
</div>
<div className="form-group">
<label>Answer 4</label>
<input
type="text"
className="form-control mt-2 mb-2"
value={answerFour}
name="answerFour"
onChange={changeHandler}
/>
</div>
</div>
</form>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={saveHandler}>
Create
</Button>
<Button color="secondary" onClick={toggle}>
Cancel
</Button>
</ModalFooter>
</Modal>
</Fragment>
);
};
export default CreateSurvey;

React.JS TypeError: Cannot read property 'value' of undefined

Having an issue with a react form and I can't figure it out. I am getting TypeError: Cannot read property 'value' of undefined when submitting. The issue started when I added "location" to the form. Not sure how this is causing it to break as I am just adding another item to the form. I have attempted to fix any typos, and when I take out the "location" it submits with no issue.
import React from "react";
import Firebase from "firebase";
import config from "./config";
class App extends React.Component {
constructor(props) {
super(props);
Firebase.initializeApp(config);
this.state = {
pallets: []
};
}
componentDidMount() {
this.getUserData();
}
componentDidUpdate(prevProps, prevState) {
if (prevState !== this.state) {
this.writeUserData();
}
}
writeUserData = () => {
Firebase.database()
.ref("/")
.set(this.state);
console.log("DATA SAVED");
};
getUserData = () => {
let ref = Firebase.database().ref("/");
ref.on("value", snapshot => {
const state = snapshot.val();
this.setState(state);
});
};
handleSubmit = event => {
event.preventDefault();
let name = this.refs.name.value;
let QTY = this.refs.QTY.value;
let uid = this.refs.uid.value;
let location = this.refs.location.value;
if (uid && name && QTY && location) {
const { pallets } = this.state;
const devIndex = pallets.findIndex(data => {
return data.uid === uid;
});
pallets[devIndex].name = name;
pallets[devIndex].QTY = QTY;
pallets[devIndex].location = location;
this.setState({ pallets });
} else if (name && QTY && location) {
const uid = new Date().getTime().toString();
const { pallets } = this.state;
pallets.push({ uid, name, QTY, location });
this.setState({ pallets });
}
this.refs.name.value = "";
this.refs.QTY.value = "";
this.refs.uid.value = "";
this.refs.location.value = "";
};
removeData = pallet => {
const { pallets } = this.state;
const newState = pallets.filter(data => {
return data.uid !== pallet.uid;
});
this.setState({ pallets: newState });
};
updateData = pallet => {
this.refs.uid.value = pallet.uid;
this.refs.name.value = pallet.name;
this.refs.QTY.value = pallet.QTY;
this.refs.location.value =pallet.location;
};
render() {
const { pallets } = this.state;
return (
<React.Fragment>
<div className="container">
<div className="row">
<div className="col-xl-12">
<h1>Creating Pallet App</h1>
</div>
</div>
<div className="row">
<div className="col-xl-12">
{pallets.map(pallet => (
<div
key={pallet.uid}
className="card float-left"
style={{ width: "18rem", marginRight: "1rem" }}
>
<div className="card-body">
<h5 className="card-title">{pallet.name}</h5>
<p className="card-text">{pallet.QTY}</p>
<p className="card-text">{pallet.location}</p>
<button
onClick={() => this.removeData(pallet)}
className="btn btn-link"
>
Delete
</button>
<button
onClick={() => this.updateData(pallet)}
className="btn btn-link"
>
Edit
</button>
</div>
</div>
))}
</div>
</div>
<div className="row">
<div className="col-xl-12">
<h1>Add new pallet here</h1>
<form onSubmit={this.handleSubmit}>
<div className="form-row">
<input type="hidden" ref="uid" />
<div className="form-group col-md-6">
<label>Name</label>
<input
type="text"
ref="name"
className="form-control"
placeholder="Name"
/>
</div>
<div className="form-group col-md-6">
<label>QTY</label>
<input
type="text"
ref="QTY"
className="form-control"
placeholder="QTY"
/>
</div>
<div className="form-group col-md-6">
<label>Location</label>
<input
type="text"
ref="QTY"
className="form-control"
placeholder="Location"
/>
</div>
</div>
<button type="submit" className="btn btn-primary">
Save
</button>
</form>
</div>
</div>
</div>
</React.Fragment>
);
}
}
export default App;
You haven't created a ref named location
Change:
<input
type="text"
ref="QTY"
className="form-control"
placeholder="Location"
/>
to:
<input
type="text"
ref="location"
className="form-control"
placeholder="Location"
/>

React component is not re-rendered after the state is changed with a dropdown list [react hooks]

I have the following React component (using hooks), which lists a number of Tasks as a dropdown list. When an item is selected from the list, I want to display an Update form. This works only when an item is selected for the first time. When I select a new item, nothing happens (although console.log(e.target.value); prints the correct value). I store the selected task's id in st_taskId.
I wonder if you see any issues in the code below:
const ManageReviewTasks = props => {
const reviewRoundId = props.match.params.reviewRoundId;
const [st_taskId, set_taskId] = useState();
useEffect(() => {
if (props.loading == false && st_taskId == null)
props.fetchReviewTasksByReviewRound(reviewRoundId);
}, [reviewRoundId, st_taskId]);
if (props.loading == true) {
return <div>Loading...</div>;
}
return (
<>
{props.reviewTasks && (
<div>
<h3>Configure the Review Tasks</h3>
<br />
{
<div>
<div>
<h4>
Tasks for <span className="font-italic">students receiving</span> feedback:
</h4>
<select
className="form-control"
onChange={e => {
e.preventDefault();
console.log(e.target.value);
set_taskId(e.target.value);
}}>
<option>--SELECT--</option>
{Object.keys(props.reviewTasks).map(id => {
const task = props.reviewTasks[id];
{
if (task.isForStudent) {
return (
<option key={id} id={id} value={id}>
{task.title}
</option>
);
}
}
})}
</select>
</div>
{props.reviewTasks[st_taskId] && (
<UpdateReviewTaskForm task={props.reviewTasks[st_taskId]} />
)}
</div>
}
</div>
)}
</>
);
};
Below is the code for the UpdateReviewTaskForm component:
const UpdateReviewTaskForm = (props) => {
const [st_Title, set_Title] = useState(props.task.title);
const [st_Description, set_Description] = useState(RichTextEditor.createValueFromString(props.task.description, 'html'));
const [st_startDate, set_startDate] = useState(new Date(props.task.startDate.replace('-', '/')));
const [st_DueDate, set_DueDate] = useState(new Date(props.task.dueDate.replace('-', '/')));
const handleCancelClick = (event) => {
event.preventDefault();
history.goBack();
}
const onSubmit_saveTask = (e) => {
e.preventDefault();
props.updateReviewTask({
Id: props.task.id,
Title: st_Title,
Description: st_Description.toString('html'),
StartDate: format(st_startDate, 'DD/MM/YYYY'),
DueDate: format(st_DueDate, 'DD/MM/YYYY'),
})
}
if (props.loading)
return <div>Updating...</div>
return (
<div>
<br/>
<br/>
<div className="p-3 bg-light">
<h3 className="text-info">Update the Task:</h3>
{
props.task &&
<form onSubmit={onSubmit_saveTask}>
<div className="form-group">
<label>Enter the title</label>
<input
//placeholder="Enter a title..."
value={st_Title}
onChange={(event) => { set_Title(event.target.value) }}
className="form-control" />
</div>
<div className="form-group">
<label>Enter a description for the assessment</label>
<RichTextEditor
value={st_Description}
onChange={set_Description}
/>
</div>
<div className="form-group">
<label>Start date to start: </label>
<DatePicker
className="form-control"
selected={st_startDate}
onChange={(date) => set_startDate(date)}
/>
</div>
<div className="form-group">
<label>Due date to complete: </label>
<DatePicker
className="form-control"
selected={st_DueDate}
onChange={(date) => set_DueDate(date)}
/>
</div>
<br />
<button type="submit" className="btn btn-primary">Submit</button>
<button type="reset" className="btn btn-light" onClick={handleCancelClick}>Cancel</button>
</form>
}
</div>
</div>
)
}
Because you are using internal state in UpdateReviewTaskForm, even if this component re-render for the second time, its state will not be reset (to the default value props.task.title for example).
One way to force the state to reset is to use a key prop in UpdateReviewTaskForm like this :
{props.reviewTasks[st_taskId] && (
<UpdateReviewTaskForm key={st_taskId} task={props.reviewTasks[st_taskId]} />
)}
Another way is to use useEffect inside UpdateReviewTaskForm to run when props.task change
useEffect(() => {
// reset the state here
}, [props.task])

Resources