Correct way to setState a property of nested object with array properties
Good day! I have a nested state with array children, and I would like to know the correct and best way to setState.
Here's a sample state object.
EDITED, Forgot to mention that lists
is an array of objects
.
this.state = {
lists:
[{
name: 'sampleList',
id: 15,
permission: {
canRead: true,
canWrite: false
}
}]
}
}
I use this to setState of the permission's properties but the state is not updated.
this.setState({
...this.state, lists: {
...this.state.lists, key: [
...this.state.lists.key, permission : {
...this.state.lists.key.permission,
canRead: !this.state.lists.key.permission.canRead
}
]
}
});
I hope you can help me. Thanks!
javascript reactjs babeljs jsx
add a comment |
Good day! I have a nested state with array children, and I would like to know the correct and best way to setState.
Here's a sample state object.
EDITED, Forgot to mention that lists
is an array of objects
.
this.state = {
lists:
[{
name: 'sampleList',
id: 15,
permission: {
canRead: true,
canWrite: false
}
}]
}
}
I use this to setState of the permission's properties but the state is not updated.
this.setState({
...this.state, lists: {
...this.state.lists, key: [
...this.state.lists.key, permission : {
...this.state.lists.key.permission,
canRead: !this.state.lists.key.permission.canRead
}
]
}
});
I hope you can help me. Thanks!
javascript reactjs babeljs jsx
In setState you are using object {...this.state.list} and not [...this.state.lists] this is problem.
– Tazo leladze
Nov 15 '18 at 19:03
add a comment |
Good day! I have a nested state with array children, and I would like to know the correct and best way to setState.
Here's a sample state object.
EDITED, Forgot to mention that lists
is an array of objects
.
this.state = {
lists:
[{
name: 'sampleList',
id: 15,
permission: {
canRead: true,
canWrite: false
}
}]
}
}
I use this to setState of the permission's properties but the state is not updated.
this.setState({
...this.state, lists: {
...this.state.lists, key: [
...this.state.lists.key, permission : {
...this.state.lists.key.permission,
canRead: !this.state.lists.key.permission.canRead
}
]
}
});
I hope you can help me. Thanks!
javascript reactjs babeljs jsx
Good day! I have a nested state with array children, and I would like to know the correct and best way to setState.
Here's a sample state object.
EDITED, Forgot to mention that lists
is an array of objects
.
this.state = {
lists:
[{
name: 'sampleList',
id: 15,
permission: {
canRead: true,
canWrite: false
}
}]
}
}
I use this to setState of the permission's properties but the state is not updated.
this.setState({
...this.state, lists: {
...this.state.lists, key: [
...this.state.lists.key, permission : {
...this.state.lists.key.permission,
canRead: !this.state.lists.key.permission.canRead
}
]
}
});
I hope you can help me. Thanks!
javascript reactjs babeljs jsx
javascript reactjs babeljs jsx
edited Nov 16 '18 at 11:44
alvirbismonte
asked Nov 15 '18 at 18:40
alvirbismontealvirbismonte
8213
8213
In setState you are using object {...this.state.list} and not [...this.state.lists] this is problem.
– Tazo leladze
Nov 15 '18 at 19:03
add a comment |
In setState you are using object {...this.state.list} and not [...this.state.lists] this is problem.
– Tazo leladze
Nov 15 '18 at 19:03
In setState you are using object {...this.state.list} and not [...this.state.lists] this is problem.
– Tazo leladze
Nov 15 '18 at 19:03
In setState you are using object {...this.state.list} and not [...this.state.lists] this is problem.
– Tazo leladze
Nov 15 '18 at 19:03
add a comment |
2 Answers
2
active
oldest
votes
You can create a copy of the lists
array, and then replace the object of the index you want to change with a copy of that same object but where you change the permission
.
Example
class App extends React.Component {
state = {
lists: [
{
name: "sampleList",
id: 15,
permission: {
canRead: true,
canWrite: false
}
}
]
};
updateList = (index, canRead, canWrite) => {
this.setState(prevState => {
const lists = [...prevState.lists];
lists[index] = { ...lists[index], permission: { canRead, canWrite } };
return { lists };
});
};
render() {
return (
<div>
<button onClick={() => this.updateList(0, false, true)}>
Update state
</button>
<div>{JSON.stringify(this.state)}</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
2
Hi @Tholle, thank you for your answer. This worked for me though I've made some updates on it to satisfy my goal. Thank you again.
– alvirbismonte
Nov 16 '18 at 15:47
2
@alvirbismonte Great! You're welcome.
– Tholle
Nov 16 '18 at 15:55
1
I wonder, what if you don’t know the index, and instead, you have an “id.” Would you usefindIndex
first?
– Waterlink
Nov 17 '18 at 7:58
@Waterlink Yeah, that would work just as well.
– Tholle
Nov 17 '18 at 9:47
add a comment |
The way to change a specific element of the array with setState
is to copy all items of array as they are without changing, except for the target item, this can be done with .map
and if
statement:
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
lists: [
{
name: 'sampleList',
id: 15,
permission: {
canRead: true,
canWrite: false
}
}
]
}
}
invertCanRead(targetId) {
this.setState({
...this.state,
lists: this.state.lists.map(list => {
if (list.id === targetId) {
// that is the one we want to modify, so let's return
// modified version:
return {
...list,
permission: {
...list.permission,
canRead: !list.permission.canRead
}
}
} else {
// else return list as is without changes because
// it's not the one we want to modify, so just copy it:
return list;
}
})
})
}
render() {
return <div>
{JSON.stringify(this.state)};
<button onClick={() => this.invertCanRead(15)}></button>
</div>
}
}
1
Hi @ilonacodes, the first answer is cleaner for me. Thank you for the effort still, it did give me ideas.
– alvirbismonte
Nov 16 '18 at 15:48
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53325985%2fcorrect-way-to-setstate-a-property-of-nested-object-with-array-properties%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can create a copy of the lists
array, and then replace the object of the index you want to change with a copy of that same object but where you change the permission
.
Example
class App extends React.Component {
state = {
lists: [
{
name: "sampleList",
id: 15,
permission: {
canRead: true,
canWrite: false
}
}
]
};
updateList = (index, canRead, canWrite) => {
this.setState(prevState => {
const lists = [...prevState.lists];
lists[index] = { ...lists[index], permission: { canRead, canWrite } };
return { lists };
});
};
render() {
return (
<div>
<button onClick={() => this.updateList(0, false, true)}>
Update state
</button>
<div>{JSON.stringify(this.state)}</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
2
Hi @Tholle, thank you for your answer. This worked for me though I've made some updates on it to satisfy my goal. Thank you again.
– alvirbismonte
Nov 16 '18 at 15:47
2
@alvirbismonte Great! You're welcome.
– Tholle
Nov 16 '18 at 15:55
1
I wonder, what if you don’t know the index, and instead, you have an “id.” Would you usefindIndex
first?
– Waterlink
Nov 17 '18 at 7:58
@Waterlink Yeah, that would work just as well.
– Tholle
Nov 17 '18 at 9:47
add a comment |
You can create a copy of the lists
array, and then replace the object of the index you want to change with a copy of that same object but where you change the permission
.
Example
class App extends React.Component {
state = {
lists: [
{
name: "sampleList",
id: 15,
permission: {
canRead: true,
canWrite: false
}
}
]
};
updateList = (index, canRead, canWrite) => {
this.setState(prevState => {
const lists = [...prevState.lists];
lists[index] = { ...lists[index], permission: { canRead, canWrite } };
return { lists };
});
};
render() {
return (
<div>
<button onClick={() => this.updateList(0, false, true)}>
Update state
</button>
<div>{JSON.stringify(this.state)}</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
2
Hi @Tholle, thank you for your answer. This worked for me though I've made some updates on it to satisfy my goal. Thank you again.
– alvirbismonte
Nov 16 '18 at 15:47
2
@alvirbismonte Great! You're welcome.
– Tholle
Nov 16 '18 at 15:55
1
I wonder, what if you don’t know the index, and instead, you have an “id.” Would you usefindIndex
first?
– Waterlink
Nov 17 '18 at 7:58
@Waterlink Yeah, that would work just as well.
– Tholle
Nov 17 '18 at 9:47
add a comment |
You can create a copy of the lists
array, and then replace the object of the index you want to change with a copy of that same object but where you change the permission
.
Example
class App extends React.Component {
state = {
lists: [
{
name: "sampleList",
id: 15,
permission: {
canRead: true,
canWrite: false
}
}
]
};
updateList = (index, canRead, canWrite) => {
this.setState(prevState => {
const lists = [...prevState.lists];
lists[index] = { ...lists[index], permission: { canRead, canWrite } };
return { lists };
});
};
render() {
return (
<div>
<button onClick={() => this.updateList(0, false, true)}>
Update state
</button>
<div>{JSON.stringify(this.state)}</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
You can create a copy of the lists
array, and then replace the object of the index you want to change with a copy of that same object but where you change the permission
.
Example
class App extends React.Component {
state = {
lists: [
{
name: "sampleList",
id: 15,
permission: {
canRead: true,
canWrite: false
}
}
]
};
updateList = (index, canRead, canWrite) => {
this.setState(prevState => {
const lists = [...prevState.lists];
lists[index] = { ...lists[index], permission: { canRead, canWrite } };
return { lists };
});
};
render() {
return (
<div>
<button onClick={() => this.updateList(0, false, true)}>
Update state
</button>
<div>{JSON.stringify(this.state)}</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
class App extends React.Component {
state = {
lists: [
{
name: "sampleList",
id: 15,
permission: {
canRead: true,
canWrite: false
}
}
]
};
updateList = (index, canRead, canWrite) => {
this.setState(prevState => {
const lists = [...prevState.lists];
lists[index] = { ...lists[index], permission: { canRead, canWrite } };
return { lists };
});
};
render() {
return (
<div>
<button onClick={() => this.updateList(0, false, true)}>
Update state
</button>
<div>{JSON.stringify(this.state)}</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
class App extends React.Component {
state = {
lists: [
{
name: "sampleList",
id: 15,
permission: {
canRead: true,
canWrite: false
}
}
]
};
updateList = (index, canRead, canWrite) => {
this.setState(prevState => {
const lists = [...prevState.lists];
lists[index] = { ...lists[index], permission: { canRead, canWrite } };
return { lists };
});
};
render() {
return (
<div>
<button onClick={() => this.updateList(0, false, true)}>
Update state
</button>
<div>{JSON.stringify(this.state)}</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
answered Nov 15 '18 at 18:51
TholleTholle
40.3k54567
40.3k54567
2
Hi @Tholle, thank you for your answer. This worked for me though I've made some updates on it to satisfy my goal. Thank you again.
– alvirbismonte
Nov 16 '18 at 15:47
2
@alvirbismonte Great! You're welcome.
– Tholle
Nov 16 '18 at 15:55
1
I wonder, what if you don’t know the index, and instead, you have an “id.” Would you usefindIndex
first?
– Waterlink
Nov 17 '18 at 7:58
@Waterlink Yeah, that would work just as well.
– Tholle
Nov 17 '18 at 9:47
add a comment |
2
Hi @Tholle, thank you for your answer. This worked for me though I've made some updates on it to satisfy my goal. Thank you again.
– alvirbismonte
Nov 16 '18 at 15:47
2
@alvirbismonte Great! You're welcome.
– Tholle
Nov 16 '18 at 15:55
1
I wonder, what if you don’t know the index, and instead, you have an “id.” Would you usefindIndex
first?
– Waterlink
Nov 17 '18 at 7:58
@Waterlink Yeah, that would work just as well.
– Tholle
Nov 17 '18 at 9:47
2
2
Hi @Tholle, thank you for your answer. This worked for me though I've made some updates on it to satisfy my goal. Thank you again.
– alvirbismonte
Nov 16 '18 at 15:47
Hi @Tholle, thank you for your answer. This worked for me though I've made some updates on it to satisfy my goal. Thank you again.
– alvirbismonte
Nov 16 '18 at 15:47
2
2
@alvirbismonte Great! You're welcome.
– Tholle
Nov 16 '18 at 15:55
@alvirbismonte Great! You're welcome.
– Tholle
Nov 16 '18 at 15:55
1
1
I wonder, what if you don’t know the index, and instead, you have an “id.” Would you use
findIndex
first?– Waterlink
Nov 17 '18 at 7:58
I wonder, what if you don’t know the index, and instead, you have an “id.” Would you use
findIndex
first?– Waterlink
Nov 17 '18 at 7:58
@Waterlink Yeah, that would work just as well.
– Tholle
Nov 17 '18 at 9:47
@Waterlink Yeah, that would work just as well.
– Tholle
Nov 17 '18 at 9:47
add a comment |
The way to change a specific element of the array with setState
is to copy all items of array as they are without changing, except for the target item, this can be done with .map
and if
statement:
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
lists: [
{
name: 'sampleList',
id: 15,
permission: {
canRead: true,
canWrite: false
}
}
]
}
}
invertCanRead(targetId) {
this.setState({
...this.state,
lists: this.state.lists.map(list => {
if (list.id === targetId) {
// that is the one we want to modify, so let's return
// modified version:
return {
...list,
permission: {
...list.permission,
canRead: !list.permission.canRead
}
}
} else {
// else return list as is without changes because
// it's not the one we want to modify, so just copy it:
return list;
}
})
})
}
render() {
return <div>
{JSON.stringify(this.state)};
<button onClick={() => this.invertCanRead(15)}></button>
</div>
}
}
1
Hi @ilonacodes, the first answer is cleaner for me. Thank you for the effort still, it did give me ideas.
– alvirbismonte
Nov 16 '18 at 15:48
add a comment |
The way to change a specific element of the array with setState
is to copy all items of array as they are without changing, except for the target item, this can be done with .map
and if
statement:
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
lists: [
{
name: 'sampleList',
id: 15,
permission: {
canRead: true,
canWrite: false
}
}
]
}
}
invertCanRead(targetId) {
this.setState({
...this.state,
lists: this.state.lists.map(list => {
if (list.id === targetId) {
// that is the one we want to modify, so let's return
// modified version:
return {
...list,
permission: {
...list.permission,
canRead: !list.permission.canRead
}
}
} else {
// else return list as is without changes because
// it's not the one we want to modify, so just copy it:
return list;
}
})
})
}
render() {
return <div>
{JSON.stringify(this.state)};
<button onClick={() => this.invertCanRead(15)}></button>
</div>
}
}
1
Hi @ilonacodes, the first answer is cleaner for me. Thank you for the effort still, it did give me ideas.
– alvirbismonte
Nov 16 '18 at 15:48
add a comment |
The way to change a specific element of the array with setState
is to copy all items of array as they are without changing, except for the target item, this can be done with .map
and if
statement:
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
lists: [
{
name: 'sampleList',
id: 15,
permission: {
canRead: true,
canWrite: false
}
}
]
}
}
invertCanRead(targetId) {
this.setState({
...this.state,
lists: this.state.lists.map(list => {
if (list.id === targetId) {
// that is the one we want to modify, so let's return
// modified version:
return {
...list,
permission: {
...list.permission,
canRead: !list.permission.canRead
}
}
} else {
// else return list as is without changes because
// it's not the one we want to modify, so just copy it:
return list;
}
})
})
}
render() {
return <div>
{JSON.stringify(this.state)};
<button onClick={() => this.invertCanRead(15)}></button>
</div>
}
}
The way to change a specific element of the array with setState
is to copy all items of array as they are without changing, except for the target item, this can be done with .map
and if
statement:
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
lists: [
{
name: 'sampleList',
id: 15,
permission: {
canRead: true,
canWrite: false
}
}
]
}
}
invertCanRead(targetId) {
this.setState({
...this.state,
lists: this.state.lists.map(list => {
if (list.id === targetId) {
// that is the one we want to modify, so let's return
// modified version:
return {
...list,
permission: {
...list.permission,
canRead: !list.permission.canRead
}
}
} else {
// else return list as is without changes because
// it's not the one we want to modify, so just copy it:
return list;
}
})
})
}
render() {
return <div>
{JSON.stringify(this.state)};
<button onClick={() => this.invertCanRead(15)}></button>
</div>
}
}
answered Nov 15 '18 at 18:57
ilonacodesilonacodes
445
445
1
Hi @ilonacodes, the first answer is cleaner for me. Thank you for the effort still, it did give me ideas.
– alvirbismonte
Nov 16 '18 at 15:48
add a comment |
1
Hi @ilonacodes, the first answer is cleaner for me. Thank you for the effort still, it did give me ideas.
– alvirbismonte
Nov 16 '18 at 15:48
1
1
Hi @ilonacodes, the first answer is cleaner for me. Thank you for the effort still, it did give me ideas.
– alvirbismonte
Nov 16 '18 at 15:48
Hi @ilonacodes, the first answer is cleaner for me. Thank you for the effort still, it did give me ideas.
– alvirbismonte
Nov 16 '18 at 15:48
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53325985%2fcorrect-way-to-setstate-a-property-of-nested-object-with-array-properties%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
In setState you are using object {...this.state.list} and not [...this.state.lists] this is problem.
– Tazo leladze
Nov 15 '18 at 19:03