How To Update Particular Object In Array Of Multiple Objects Dynamically
Solution 1:
You can get, first of all, the tabs of the state:
const { tabs } = this.state;
// here you code to decide what tab do you want to updateconst tabSelected = tabs[0];
const { DroppedDetails } = tabSelected;
DroppedDetails[0]= {
name: "sagar111"
};
// You can edit another one or add a new one to the array also.
DroppedDetails[1]= {
name: "NameEdited"
};
DroppedDetails.push({ name: "New Name" })
And set state a new state:
this.setState(
{ tabs: tabs.map(t => t === tabSelected ? { ...tabSelected, DroppedDetails }) : t });
But it could be in this way too:
this.setState(tabs);
Because the original references were updated.
At the end DroppedDetails
and tabs[0].DroppedDetails[0]
are the same object.
how can i do setState for inner loop of array of objects???
It's not recommended the use of setState in a forloop. Check this Calling setState in a loop only updates state 1 time
Solution 2:
You can easily do that (this changes the name to lower case):
const { tabs } = this.state;
tabs.map(tab => {
// Do something with your tab value like the followingconst newDroppedDetails = tab.map(({ name }) => ({ name: name.toLowerCase() });
return {
...tab,
DroppedDetails: newDroppedDetails
}
});
The key point here is to not mutate objects or arrays, but to create a new reference to objects that you modify, so the shallow compare on PureComponents will always work properly.
Solution 3:
Applying the same concepts from your original codesandbox, we can do something like this to edit each individual Dropdown Detail.
working sandbox https://codesandbox.io/s/tab-creator-v2-8hc7c
import React from "react";
import ReactDOM from "react-dom";
import uuid from "uuid";
import"./styles.css";
classAppextendsReact.Component{
state = {
tabs: [
{
id: 1,
name: "Tab 1",
content: "Wow this is tab 1",
DroppedDetails: [
{ name: "Bhanu", editing: false },
{ name: "Sagar", editing: false }
]
},
{
id: 2,
name: "Tab 2",
content: "Look at me, it's Tab 2",
DroppedDetails: [
{ name: "Christopher", editing: false },
{ name: "Ngo", editing: false }
]
}
],
currentTab: {
id: 1,
name: "Tab 1",
content: "Wow this is tab 1",
DroppedDetails: [
{ name: "Bhanu", editing: false },
{ name: "Sagar", editing: false }
]
},
editMode: false,
editTabNameMode: false
};
handleDoubleClick = () => {
this.setState({
editTabNameMode: true
});
};
handleEditTabName = e => {
const { currentTab, tabs } = this.state;
const updatedTabs = tabs.map(tab => {
if (tab.id === currentTab.id) {
return {
...tab,
name: e.target.value
};
} else {
return tab;
}
});
this.setState({
tabs: updatedTabs,
currentTab: {
...currentTab,
name: e.target.value
}
});
};
handleOnBlur = () => {
this.setState({
editTabNameMode: false
});
};
handleDetailChange = (e, id, index) => {
const { tabs, currentTab } = this.state;
const updatedCurrentTab = { ...currentTab };
updatedCurrentTab.DroppedDetails = updatedCurrentTab.DroppedDetails.map(
(detail, detailIndex) => {
if (index == detailIndex) {
return {
...detail,
name: e.target.value
};
} else {
return detail;
}
}
);
const updatedTabs = tabs.map(tab => {
if (tab.id == id) {
return {
...tab,
DroppedDetails: tab.DroppedDetails.map((detail, detailIndex) => {
if (detailIndex == index) {
return {
...detail,
name: e.target.value
};
} else {
return detail;
}
})
};
} else {
return tab;
}
});
this.setState({
tabs: updatedTabs,
currentTab: updatedCurrentTab
});
};
createTabs = () => {
const { tabs, currentTab, editTabNameMode } = this.state;
const allTabs = tabs.map(tab => {
return (
<li>
{editTabNameMode && currentTab.id === tab.id ? (
<input
value={tab.name}
onBlur={this.handleOnBlur}
onChange={this.handleEditTabName}
/>
) : (
<button
className={currentTab.id === tab.id ? "tab active" : "tab"}
onClick={() => this.handleSelectTab(tab)}
onDoubleClick={() => this.handleDoubleClick(tab)}
>
{tab.name}
</button>
)}
</li>
);
});
return <ul className="nav nav-tabs">{allTabs}</ul>;
};
handleSelectTab = tab => {
this.setState({
currentTab: tab,
editMode: false,
editTabNameMode: false
});
};
handleAddTab = () => {
const { tabs } = this.state;
const newTabObject = {
id: uuid(),
name: `Tab ${tabs.length + 1}`,
content: `This is Tab ${tabs.length + 1}`,
DroppedDetails: []
};
this.setState({
tabs: [...tabs, newTabObject],
currentTab: newTabObject,
editMode: false,
editTabNameMode: false
});
};
handleDeleteTab = tabToDelete => {
const { tabs } = this.state;
const tabToDeleteIndex = tabs.findIndex(tab => tab.id === tabToDelete.id);
const updatedTabs = tabs.filter((tab, index) => {
return index !== tabToDeleteIndex;
});
const previousTab =
tabs[tabToDeleteIndex - 1] || tabs[tabToDeleteIndex + 1] || {};
this.setState({
tabs: updatedTabs,
editMode: false,
editTabNameMode: false,
currentTab: previousTab
});
};
setEditMode = () => {
this.setState({
editMode: !this.state.editMode
});
};
handleContentChange = e => {
const { tabs, currentTab } = this.state;
const updatedTabs = tabs.map(tab => {
if (tab.name === currentTab.name) {
return {
...tab,
content: e.target.value
};
} else {
return tab;
}
});
this.setState({
tabs: updatedTabs,
currentTab: {
...currentTab,
content: e.target.value
}
});
};
handleOnDetailBlur = (id, index) => {
const { tabs, currentTab } = this.state;
const updatedCurrentTab = { ...currentTab };
updatedCurrentTab.DroppedDetails = updatedCurrentTab.DroppedDetails.map(
(detail, detailIndex) => {
if (index == detailIndex) {
return {
...detail,
editing: false
};
} else {
return detail;
}
}
);
const updatedTabs = tabs.map(tab => {
if (tab.id == id) {
return {
...tab,
DroppedDetails: tab.DroppedDetails.map((detail, detailIndex) => {
if (detailIndex == index) {
return {
...detail,
editing: false
};
} else {
return detail;
}
})
};
} else {
return tab;
}
});
this.setState({
tabs: updatedTabs || [],
currentTab: updatedCurrentTab
});
};
handleDoubleClickDetail = (id, index) => {
const { tabs, currentTab } = this.state;
const updatedCurrentTab = { ...currentTab };
updatedCurrentTab.DroppedDetails = updatedCurrentTab.DroppedDetails.map(
(detail, detailIndex) => {
if (index == detailIndex) {
return {
...detail,
editing: true
};
} else {
return detail;
}
}
);
const updatedTabs = tabs.map(tab => {
if (tab.id == id) {
return {
...tab,
DroppedDetails: tab.DroppedDetails.map((detail, detailIndex) => {
if (detailIndex == index) {
return {
...detail,
editing: true
};
} else {
return detail;
}
})
};
} else {
return tab;
}
});
this.setState({
tabs: updatedTabs || [],
currentTab: updatedCurrentTab
});
};
createContent = () => {
const { currentTab } = this.state;
return (
<div>
<div>
<p>{currentTab.content}</p>
<div>
<h4>Dropped Details</h4>
{currentTab.DroppedDetails ? (
<div>
{currentTab.DroppedDetails.map((detail, index) => {
if (detail.editing) {
return (
<div>
<input
value={detail.name}
onChange={e =>
this.handleDetailChange(e, currentTab.id, index)
}
onBlur={() =>
this.handleOnDetailBlur(currentTab.id, index)
}
/>
</div>
);
} else {
return (
<p
onDoubleClick={() =>
this.handleDoubleClickDetail(currentTab.id, index)
}
>
{detail.name}
</p>
);
}
})}
</div>
) : (
""
)}
</div>
</div>
{currentTab.id ? (
<div style={{ display: "flex", justifyContent: "space-between" }}>
<button className="edit-mode-button" onClick={this.setEditMode}>
Edit
</button>
<button onClick={() => this.handleDeleteTab(currentTab)}>
Delete
</button>
</div>
) : (
""
)}
</div>
);
};
render() {
const { currentTab, editMode } = this.state;
return (
<div className="container">
<div className="well">
<button className="add-tab-button" onClick={this.handleAddTab}>
<i className="text-primary fas fa-plus-square" /> Add Tab
</button>
{this.createTabs()}
<div className="tab-content">
{editMode ? (
<div>
<textarea
onChange={this.handleContentChange}
value={currentTab.content}
/>
<button className="save-button" onClick={this.setEditMode}>
Done
</button>
</div>
) : (
this.createContent()
)}
</div>
</div>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
To activate "edit-mode" double-click a dropped-detail. The input should appear in its place and you can type in the new text. When complete, click out of the input and it will finalize the updated text :)
Post a Comment for "How To Update Particular Object In Array Of Multiple Objects Dynamically"