Panel is a datamodel fetched from database. avialablePanels is a dropdown where I can select an option I want. PanelCode dropdown is populated using a lookup table because it acts as a form where the displayed value is what Panel['PanelCode'] has and other values with which I can update. When I update a value of Panel[PanelCode] with the help of indexing using the PanelCode dropdown form it initially updates the value in the Panel['PanelCode'] array. Now lets say I want to update another value in the Panel['PanelCode'] and save them together as soon as I select another option from avialablePanels the first updated value of Panel['PanelCode'] is lost.
Panel: {
PanelCode: [ 1, 4 ]
}
availablePanels:[
{ OptionCode: 'R1-1', OptionKey: 1, OptionValue: 'Stop' },
{ OptionCode: 'R1-3P',OptionKey: 4,OptionValue: 'All Way (plaque)'}
]
export default class PanelTest extends Component {
constructor(props) {
super(props);
console.log(this.props.pointModel)
this.state = {...this.props.pointModel,
availablePanels:[],
selectedIndex: 0,
selectedPanel: null,
tempPanelCode: this.props.pointModel.Panel.PanelCode[0]===null?0:
this.props.pointModel.Panel.PanelCode[0],
}
}
render() {
return(
<Container>
{this.state.availablePanels.length>0 &&
<PtSelect label="Available Panel"
options={this.state.availablePanels}
name="selectedPanel" defaultVal={this.state.selectedPanel}
onChange={this.onChangeSelectedPanelDropdown} />}
{this.renderPanelinfo()}
</Container>
)
}
onChangeSelectedPanelDropdown = (e) => {
const { target } = e;
const {name, value} = target;
let indexVal = this.state.Panel.PanelCode.indexOf(parseInt(value))
this.setState({ [name]: parseInt(value),
selectedIndex:indexVal,
tempPanelCode: this.props.pointModel.Panel.PanelCode[indexVal]===null?0:
this.props.pointModel.Panel.PanelCode[indexVal]
});
}
renderPanelinfo = () =>{
const {typeOptions} = DropdownLib.getSignNum().Signs_Types;
/* typeOptions looks like availablePanels but with more options */
return (
<div>
<PtSelect label="Panel Code" options={typeOptions}
disabled={this.props.disabled}
name="PanelCode" defaultVal={this.state.tempPanelCode}
onChange={this.onChangeDropdown} />
</div>
)
}
getAvaialablePanels=()=>{
const availablePanelOptions = []
const optionKey = []
//const optionvalue = []
fetch(`${config.server}/getavailablepanels/`+this.state.Support.SignId)
.then(response=>
{
return response.json();
})
.then(data=>{
for (var i =0;i<data.length;i++){
availablePanelOptions.push(data[i]['OptionCode'])
optionKey.push(data[i]['OptionKey'])
//optionvalue.push(data[i]['OptionValue'])
}
let dropOptions = availablePanelOptions.map((option,idx)=>{
return {key:optionKey[idx],value: optionKey[idx], label:option}
});
this.setState({
availablePanels:dropOptions
});
})
.catch(error=>{
console.log(error);
});
}
onChangeDropdown = (e) => {
const { target } = e;
const {name, value} = target;
this.props.triggerNeedSave();
// eslint-disable-next-line
let stateVariable = 'temp'+[name]
this.setState({
[stateVariable]: parseInt(value)
});
this.props.pointModel.Panel[name][this.state.selectedIndex] = parseInt(value);
console.log(this.state)
}
componentDidMount(){
this.getAvaialablePanels()
}
}
Any help is really appreciated.
Related
I've create an autocomplete search input bar using AWS Cloudscape. When I attempt to use the onSelect to save state, it does not save state. When I select a second item from the search bar, the first item then shows up. I assume this is a state async issue. I need the most recent selection, how do I get that?
import React from "react";
import Regions from "./trailforks_regions.json"
import RegionNames from "./region_names.json"
import * as dfd from "danfojs";
import { Autosuggest } from '#cloudscape-design/components';
export class AutoCompleteInputComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
df: new dfd.DataFrame(Regions),
value: null,
final_value: "",
options: [],
status: "loading",
regionContext: [],
uri_value: "",
loaded: false
};
}
lookupRegionUriName() {
console.log("Checking for uri region name on:" + this.state.final_value)
let region_name_split = this.state.final_value.split(",")[0]
let query_df = this.state.df.query(this.state.df["name"].eq(region_name_split))
let uri_name = query_df["region_uri_name"].values
console.log("found:" + uri_name)
return uri_name
}
handleChange = event => {
this.setState({ value: event.detail.value });
};
handleSelect = event => {
console.log(event) // This shows the correct data! But the set state does not set this data.
this.setState({ final_value: event.detail.value });
this.lookupRegionUriName(this.state.final_value)
};
handleLoadItems = ({ detail: { filteringText, firstPage, samePage } }) => {
this.filteringText = filteringText;
var my_options = RegionNames.filter(regions => regions.toLowerCase().startsWith(this.filteringText.toLowerCase()))
var region_values = []
for (var i = 0; i <= my_options.length; i++) {
region_values.push({ value: my_options[i] })
}
this.setState({
options: region_values.slice(0, 25),
status: 'loading',
});
};
enteredTextLabel = value => `Use: "${value}"`;
renderInput() {
if (this.state.df != null) {
const { status, value, options, final_value, uri_value } = this.state;
return (
<>
<Autosuggest
onChange={this.handleChange}
onSelect={this.handleSelect}
onLoadItems={this.handleLoadItems}
value={value}
options={options}
enteredTextLabel={this.enteredTextLabel}
ariaLabel="Autosuggest example with suggestions"
placeholder="Enter Trailforks Region Name"
empty="No matches found"
finishedText={this.filteringText ? `End of "${this.filteringText}" results` : 'End of all results'}
//status={status}
loadingText="searching"
filteringType="manual"
/>
</>
)
} else {
return (<></>)
}
}
render() {
return (
<>
{this.renderInput()}
</>
)
}
}
Figured it out. It was a state issue, here are the changes for future people:
import React from "react";
import Regions from "./regions.json"
import RegionNames from "./region_names.json"
import * as dfd from "danfojs";
import { Autosuggest } from '#cloudscape-design/components';
export class AutoCompleteInputComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
df: new dfd.DataFrame(Regions),
value: null,
final_value: "",
options: [],
status: "loading",
regionContext: [],
uri_value: "",
loaded: false
};
}
updateRegion(state_object) {
this.lookupRegionUriName()
return state_object.final_value
}
lookupRegionUriName() {
console.log("Checking for uri region name on:" + this.state.final_value)
let region_name_split = this.state.final_value.split(",")[0]
let query_df = this.state.df.query(this.state.df["name"].eq(region_name_split))
let uri_name = query_df["region_uri_name"].values
this.setState({uri_value: uri_name})
console.log("found:" + uri_name)
}
handleChange = event => {
this.setState({ value: event.detail.value });
};
handleSelect = event => {
console.log(event) // This shows the correct data! But the set state does not set this data.
this.setState({ final_value: event.detail.value });
this.lookupRegionUriName(this.state.final_value)
};
handleLoadItems = ({ detail: { filteringText, firstPage, samePage } }) => {
this.filteringText = filteringText;
var my_options = RegionNames.filter(regions => regions.toLowerCase().startsWith(this.filteringText.toLowerCase()))
var region_values = []
for (var i = 0; i <= my_options.length; i++) {
region_values.push({ value: my_options[i] })
}
this.setState({
options: region_values.slice(0, 25),
status: 'loading',
});
};
enteredTextLabel = value => `Use: "${value}"`;
renderInput() {
if (this.state.df != null) {
const { status, value, options, final_value, uri_value } = this.state;
return (
<>
<Autosuggest
onChange={this.handleChange}
onSelect={event => {this.setState({final_value: event.detail.value}, () => {this.updateRegion(this.state)})}}
//onSelect={this.handleSelect}
onLoadItems={this.handleLoadItems}
value={value}
options={options}
enteredTextLabel={this.enteredTextLabel}
ariaLabel="Autosuggest example with suggestions"
placeholder="Enter Trailforks Region Name"
empty="No matches found"
finishedText={this.filteringText ? `End of "${this.filteringText}" results` : 'End of all results'}
status={status}
loadingText="searching"
filteringType="manual"
/>
</>
)
} else {
return (<></>)
}
}
render() {
return (
<>
{this.renderInput()}
</>
)
}
}
I need help in my react code. I am displaying the list of checkbox items using api. My JSON file contains the data which is having IsAssigned True/False. If isAssigned is true for that item, item checkbox will be pre-checked on page load.
Now, I want to change the selection of Checkboxlist items. How can I get the id's of selected Checkboxes and call post/put api calls to make changes in the database.
There are checkboxes that are pre-selected isAssigned=true, unselect the pre-selected checkboxes isAssigned= false, select the checkboxes that are not pre-selected earlier.
Please find my react code and json data below. Also, help me out on achieving the above,
import React from "react";
export class SetDescItems extends React.Component {
static displayName = Assign_TemplateDescriptions.name;
constructor(props) {
super(props);
this.state = {
ProdDescrlist: [],
checkedItems: new Map(),
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
var isChecked = event.target.checked;
var item = event.target.value;
var id = event.target.id;
this.setState(prevState => ({ checkedItems: prevState.checkedItems.set(id, item, isChecked) }));
}
handleSubmit(event) {
event.preventDefault();
//Create an Array.
var checkedItems = new Array();
//Reference all the CheckBoxes
var chks = document.getElementsByTagName("INPUT");
// Loop and push the checked CheckBox id's in Array.
for (var i = 0; i < chks.length; i++) {
if (chks[i].checked) {
checkedItems.push(chks[i].id);
}
}
//Display the selected CheckBox id's.
if (checkedItems.length > 0) {
checkedItems = checkedItems.join(",");
console.log("Selected ids: " + checkedItems);
}
const data = checkedItems;
//write post api here
}
componentDidMount() {
this.getProdDescriptions();
}
async getProdDescriptions () {
const url = “/api/getDescriptions”;
await fetch(url)
.then(response => response.json())
.then((data) => {
this.setState({
ProdDescrlist: data,
loading: false
})
console.log(this.state.ProdDescrlist)
})
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit} >
<ul style={{ listStyle: 'none' }}>
{
(this.state.ProdDescrlist.map((item, index) => {
return (
<li key={index}>
<input type="checkbox"
id={item.ProdDescription_ID}
defaultChecked={item.isAssigned == "TRUE"?true:false}
value={item.DescriptionTextPlain}
onChange={this.handleChange} />
{item.DescriptionTextPlain}
</li>
)
}
))
}
</ul>
<button type="submit">Submit</button>
</form>
</div>
);
}
}
export default SetDescItems;
[{"ProdDescription_ID":2863,"isAssigned":"TRUE","DisplaySequence":0,"DescriptionTextPlain":"A1Testig"},
{"ProdDescription_ID":2865,"isAssigned":"TRUE","DisplaySequence":0,"DescriptionTextPlain":"test"},
{"ProdDescription_ID":1778,"isAssigned":"FALSE","DisplaySequence":0,"DescriptionTextPlain":"Testing4"},
{"ProdDescription_ID":2864,"isAssigned":"FALSE","DisplaySequence":0,"DescriptionTextPlain":"A2 "},
{"ProdDescription_ID":1544,"isAssigned":"FALSE","DisplaySequence":5,"DescriptionTextPlain":"ProductGuide"},
{"ProdDescription_ID":1535,"isAssigned":"TRUE","DisplaySequence":10,"DescriptionTextPlain":"testexample"},
{"ProdDescription_ID":1536,"isAssigned":"FALSE","DisplaySequence":15,"DescriptionTextPlain":"Note"}]
You need to use checked prop in input tag
import "./styles.css";
import React from "react";
export class SetDescItems extends React.Component {
constructor(props) {
super(props);
this.state = {
ProdDescrlist: [],
checkedItems: []
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
const id = parseInt(event.target.id, 10);
const index = this.state.checkedItems.indexOf(id);
const updatedArray = [...this.state.checkedItems];
if (index !== -1) {
updatedArray.splice(index, 1);
} else {
updatedArray.push(id);
}
this.setState((prevState) => ({
checkedItems: updatedArray
}));
}
handleSubmit(event) {
event.preventDefault();
let value = "";
this.state.checkedItems.forEach((item) => {
if (item) {
value = value === "" ? item : value + "," + item;
}
});
if (value !== "") {
alert(value);
}
}
componentDidMount() {
this.getProdDescriptions();
}
async getProdDescriptions() {
const url = "/api/getDescriptions";
await fetch(url)
.then((response) => response.json())
.then((data) => {
let items = data.reduce((acc, item) => {
if(item.isAssigned === "TRUE") acc.push(item.ProdDescription_ID);
return acc;
}, []);
this.setState({
ProdDescrlist: data,
loading: false,
checkedItems: items
});
});
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<ul style={{ listStyle: "none" }}>
{this.state.ProdDescrlist.map((item, index) => {
return (
<li key={index}>
<input
type="checkbox"
id={item.ProdDescription_ID}
defaultChecked={item.isAssigned === "TRUE" ? true : false}
value={item.DescriptionTextPlain}
onChange={this.handleChange}
/>
{item.DescriptionTextPlain}
</li>
);
})}
</ul>
<button type="submit">Submit</button>
</form>
</div>
);
}
}
I have managed to create my function to select a single or multiple boxes. On the single ones I don't have any issue, I mean when you click a box it is checked or unchecked.
But it is not the same case with the select all. Any ideas how can I fix that? (I am using material-ui library for my boxes, but basically they are simple HTML input)
Select all component and function:
<Checkbox
name="checkboxes"
checked={this.state.allCheckboxes}
onChange={this.handleAllCheckboxes}
indeterminate
/>Select All
Function:
handleAllCheckboxes = (e) => {
let responseObj = this.state.items;
let prepareObj = {};
if(e.target.checked){
//to do add loop to check all check box
responseObj.forEach(function(item){
if(item.documentId !== null && item.documetNumber !== null ){
prepareObj[item.documentId] = item.documentNumber;
// this.refs.documentId
}
});
let toSee = Object.keys(prepareObj).length > 0 ? true : false;
this.setState({
docList: prepareObj,
visible: toSee
})
let checkboxes = document.getElementsByName('DocCheckbox')
checkboxes.forEach(function(checkbox){
checkbox.checked = checkbox.checked
})
console.log(checkboxes)
} else {
//to do add loop to uncheck all check box
this.setState({
prepareObj: {}
})
}
console.log(prepareObj);
};
Select single component and function:
<Checkbox
name='DocCheckbox'
type='checkbox'
color='default'
value={JSON.stringify({ documentId: rowData.documentId, documentNumber: rowData.documentNumber })}
onClick={this.handleCheckboxClick}/>
Function:
handleCheckboxClick = (e, id) => {
if (id) {
} else {
let parsedVal = JSON.parse(e.target.value);
// console.log(e.target.value)
let newDocList = { ...this.state.docList };
if (e.target.checked) {
this.setState({
singleCheckbox:true
})
newDocList[parsedVal.documentId] = parsedVal.documentNumber;
} else {
delete newDocList[parsedVal.documentId];
this.setState({
singleCheckbox:false
})
}
let toSee = Object.keys(newDocList).length > 0 ? true : false;
this.setState(
{
docList: newDocList,
visible: toSee
},
() => {
console.log(this.state.docList);
}
);
}
};
UPDATE
Answer of my code based to the reply of #norbitrial
( The answer is based on my properties , calls and data so feel free to modify it for your purpose )
Step 1 - Create a constructor to maintain your data and global checked state
constructor(props) {
super(props);
this.state = {
docList: {},
checked: false,
hasToCheckAll: false
}
}
Step 2 - Create functions to handle single and multiple checkboxes
Handle single checkbox
handleCheckboxClick = (clickedItem) => {
console.log(clickedItem)
// let parsedVal = JSON.parse(e.target.value);
let newDocList = { ...this.state.docList };
if (!clickedItem.checked) {
newDocList[clickedItem.documentId] = clickedItem.documentNumber;
console.log(newDocList)
} else {
delete newDocList[clickedItem.documentId];
}
let toSee = Object.keys(newDocList).length > 0 ? true : false;
console.log(toSee)
this.setState(
{
docList: newDocList,
visible: toSee
}, ()=>{
console.log(newDocList)
});
const updatedArray = this.state.items.map((item) => {
item.checked = item.documentId === clickedItem.documentId ? !item.checked : item.checked;
return item;
});
this.setState({
items: updatedArray,
});
};
Handle all checkboxes
handleAllCheckboxes = (e) => {
const hasToCheckAll = !this.state.hasToCheckAll;
const updatedArray = this.state.items.map((item) => {
item.checked = hasToCheckAll;
return item;
});
console.log(updatedArray)
let responseObj = this.state.items;
let prepareObj = {};
if (e.target.checked) {
//to do add loop to check all check box
responseObj.forEach(function (item) {
if (item.documentId !== null && item.documetNumber !== null) {
prepareObj[item.documentId] = item.documentNumber;
}
});
let toSee = Object.keys(prepareObj).length > 0 ? true : false;
console.log(toSee)
this.setState({
docList: prepareObj,
// allCheckboxes: true,
items: updatedArray,
hasToCheckAll,
visible: toSee
})
let checkboxes = document.getElementsByName('checkAll')
checkboxes.forEach(function (checkbox) {
checkbox.checked = e.target.checked
})
console.log(checkboxes)
} else {
console.log(updatedArray)
this.setState({
docList: {},
hasToCheckAll:false
})
}
};
Step 3 - Insert the state of the checked boxes inside into the object . And loop over them ( again this is coming from the response from my Back End so for everyone this step will be different )
.then((response) => {
// handle success
let dataItem = response.data.bills;
let prepareDataItem = [];
dataItem.forEach(function (item) {
item.checked = false;
prepareDataItem.push(item);
})
Step 4 - Render the checkboxes (these checkboxes are based on material-ui library , but it can work for a simple inputs also)
<Checkbox
name='DocCheckBox'
type='checkbox'
checked={rowData.checked}
color='default'
value={JSON.stringify({ documentId: rowData.documentId, documentNumber: rowData.documentNumber })}
onChange={() => this.handleCheckboxClick(rowData)}/>
<Checkbox
name="checkboxes"
checked={this.state.hasToCheckAll}
onChange={this.handleAllCheckboxes}
indeterminate
/>Select All
I would change a bit how you are handling these things in the application.
Technically you are manipulating the DOM directly, instead of leaving it to React with its states. In this case there is a definitely better way to handle checkbox states in the UI.
The solution:
1. Changed default state:
Let me state that I don't have the real data structure what you have so I have the following in the constructor just for the representation:
constructor(props:any) {
super(props);
this.state = {
items: [
{ documentId: 1, documentNumber: 1234, checked: false },
{ documentId: 2, documentNumber: 1235, checked: false },
{ documentId: 3, documentNumber: 1236, checked: false },
],
hasToCheckAll: false,
}
}
As you can see the items have checked property in order to handle them in the state.
2. Rendering the checkboxes differently
In the render function I have changed couple of things:
render() {
return (
<div>
<Checkbox
name="checkboxes"
checked={this.state.hasToCheckAll}
onChange={() => this.handleAllCheckboxes()}
indeterminate
/>Select All
{this.state.items.map((item:any) => {
return <div key={item.documentNumber}>
<Checkbox
name="DocCheckbox"
color="default"
checked={item.checked}
value={JSON.stringify({ ...item.documentId, ...item.documentNumber })}
onChange={() => this.handleCheckboxClick(item)}/> {item.documentNumber}
</div>
})}
</div>
)
}
3. Handling checkbox state is also changed:
Take a look at the following handlers:
handleAllCheckboxes = () => {
const hasToCheckAll = !this.state.hasToCheckAll;
const updatedArray = this.state.items.map((item:any) => {
item.checked = hasToCheckAll;
return item;
});
this.setState({
...this.state,
items: updatedArray,
hasToCheckAll: hasToCheckAll,
});
};
handleCheckboxClick = (clickedItem:any) => {
const updatedArray = this.state.items.map((item:any) => {
item.checked = item.documentId === clickedItem.documentId ? !item.checked : item.checked;
return item;
});
this.setState({
...this.state,
items: updatedArray,
});
};
The result:
Of course you can extend this example with your data manipulation if there is a further need. The solution has been built with TypeScript - I had a project opened with that - but you can remove types where it has been added.
The above example works like charm, I hope this helps!
I am trying to add a FontAwesome arrow next to each item in my menu that has children (i.e. I want to indicate that you can click the element to display more data within that category). The menu is populated with json data from an API, and because it is so many nested objects, I decided to use recursion to make it work. But now I am having trouble adding an arrow only to the elements that have more data within it, instead of every single element in the menu.
Does anyone have an idea of how I could change it so the arrow only shows up next to the elements that need it? See below for image
class Menu extends React.Component {
state = {
devices: [],
objectKey: null,
tempKey: []
};
This is where I'm currently adding the arrow...
createMenuLevels = level => {
const { objectKey } = this.state;
const levelKeys = Object.entries(level).map(([key, value]) => {
return (
<ul key={key}>
<div onClick={() => this.handleDisplayNextLevel(key)}>{key} <FontAwesome name="angle-right"/> </div>
{objectKey[key] && this.createMenuLevels(value)}
</ul>
);
});
return <div>{levelKeys}</div>;
};
handleDisplayNextLevel = key => {
this.setState(prevState => ({
objectKey: {
...prevState.objectKey,
[key]: !this.state.objectKey[key]
}
}));
};
initializeTK = level => {
Object.entries(level).map(([key, value]) => {
const newTemp = this.state.tempKey;
newTemp.push(key);
this.setState({ tempKey: newTemp });
this.initializeTK(value);
});
};
initializeOK = () => {
const { tempKey } = this.state;
let tempObject = {};
tempKey.forEach(tempKey => {
tempObject[tempKey] = true;
});
this.setState({ objectKey: tempObject });
};
componentDidMount() {
axios.get("https://www.ifixit.com/api/2.0/categories").then(response => {
this.setState({ devices: response.data });
});
const { devices } = this.state;
this.initializeTK(devices);
this.initializeOK();
this.setState({ devices });
}
render() {
const { devices } = this.state;
return <div>{this.createMenuLevels(devices)}</div>;
}
}
This is what it looks like as of right now, but I would like it so items like Necktie and Umbrella don't have arrows, since there is no more data within those items to be shown
You could check in the map loop from createMenuLevels if the value is empty or not and construct the div based on that information.
createMenuLevels = level => {
const { objectKey } = this.state;
const levelKeys = Object.entries(level).map(([key, value]) => {
//check here if childs are included:
var arrow = value ? "<FontAwesome name='angle-right'/>" : "";
return (
<ul key={key}>
<div onClick={() => this.handleDisplayNextLevel(key)}>{key} {arrow} </div>
{objectKey[key] && this.createMenuLevels(value)}
</ul>
);
});
return <div>{levelKeys}</div>;
};
Instead of just checking if the value is set you could check if it is an array with: Array.isArray(value)
I have initialized some const, lets say A, using getDerivedStateFromProps. Now I want to update the value on some action using setState but it's not working.
constructor(props) {
super(props)
this.state = {
A: []
}
static getDerivedStateFromProps(nextProps, prevState) {
const A = nextProps.A
return {
A
}
}
handleDragStart(e,data) {
e.dataTransfer.setData('item', data)
}
handleDragOver(e) {
e.preventDefault()
}
handleDrop(e, cat) {
const id = e.dataTransfer.getData('item')
const item = find(propEq('id', Number(id)), this.state.A)
const data = {
...item.data,
category: cat,
}
const val = {
...item,
data
}
this.setState({
A: item,
})
}
}
**Listing the items and Drag and Drop to Categorize**
{this.state.A.map((item, index) => (
<ListRow
key={`lm${index}`}
draggable
name={item.name ? item.name : ''}
description={item.data ? item.data.description : ''}
type={item.data ? item.data.target_types : ''}
source={item.data ? item.data.source : ''}
stars={item.data ? item.data.stars : []}
onDragStart={e => this.handleDragStart(e, item.id)}
onDragOver={e => this.handleDragOver(e)}
onDrop={e => this.handleDrop(e, 'process')}
onModal={() => this.handleToggleModal(item)}
/>
))}
I expect the value of A to be an item from HandleDrop but it's returning the same value that is loaded from getDerivedStateFromProps.
Here's how I solved this problem.
I used componentDidUpdate instead of getDerivedStatesFromProps.
componentDidUpdate(prevProps) {
if (!equals(this.props.A, prevPropsA)) {
const A = this.props.A
this.setState({
A
})
}
}
And the handleDrop function as
handleDrop(e, cat) {
const id = e.dataTransfer.getData('item')
const item = find(propEq('id', Number(id)), this.state.A)
const data = {
....data,
category: cat,
}
const val = {
...quota,
data
}
let {A} = this.state
const index = findIndex(propEq('id', Number(id)), A)
if (!equals(index, -1)) {
A = update(index, val, A)
}
this.setState({
A
})
}
Thank you very much for all of your help. Any suggestions or feedback for optimizing this sol will be highly appreciated. Thanks