8

How can I write this better , I want to do it with setState instead of this.state.floors.push as I know that is bad practice but I couldnt figure it out. Im using react native.

FloorAPI.getFloorsByBuildingID(this.state.buildingID).then((response) => response.d.data.map((value) => {
  console.log(value.floorName)
  this.state.floors.push({value: value.floorName})
}))
1

9 Answers 9

31
// Create a new array based on current state:
let floors = [...this.state.floors];

// Add item to it
floors.push({ value: floorName });

// Set state
this.setState({ floors });
Sign up to request clarification or add additional context in comments.

3 Comments

Simple and works great, thank you. Although whats with the three periods, why is that required?
It was a little weird for me to wrap my head around but the ... is part of a concept called "destructuring": developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
best meaningful coding.
5

In hooks form u may use

setState((prevVals) => [...prevVals,newVals])

Comments

3

For now, the best possible and simplest way is

  this.setState(previousState => ({
      floors: [...previousState.floors, {"value": value.floorName}]
  }));

2 Comments

i got error TypeError : Invalid attempt to spread non-iterable instance
@RayCoder The reason why you're getting TypeError : Invalid attempt to spread non-iterable instance because the data which you are using to destruct is not an array and the reason it not iterable and the reason why you got the error.
1
FloorAPI.getFloorsByBuildingID(this.state.buildingID).then((response) => { 
  // get current floors
  const { floors } = this.state;

  // get new floors after api request
  const newfloors = response.d.data.map((value) => ({value: value.floorName}))

  // set the new state by combining both arrays
  this.setState({ floors: [...floors, ...newfloors] });
})

Comments

0

You can make a new variable and push to the variable then set the state after the map is complete

var tempArray = []

FloorAPI.getFloorsByBuildingID(this.state.buildingID).then((response) => response.d.data.map((value) => {
  tempArray.push({value: value.floorName})
}))

this.setState({floors: tempArray})

Comments

0
const { floors } = this.state;

// Add item to it
floors.push({ value: 5 });

// Set state
this.setState({ floors });

Comments

0

You can use

this.setState({floors: [{value: value.floorName}]}); 

in order to use set state.

1 Comment

This works in a way but its only putting one item in the array, and I need all of the floors to be in this array since its going to be populating a dropdown menu.
0

I tried a lot but what worked for me was .concat() function

import react,{useState} from 'react'

const [files,setFiles] = useState([]);

function addUp(acceptedFiles){
 // the code below adds up to the state, using the args
 setFiles((prev) => {
   return prev.concat(acceptedFiles);
 }); 
}

return <div> </div>

Comments

-1

You can always use the previous state.

setState((prevState)=>({
   floors: prevState.floors.push({...})
});

Thats a nice way to avoid directly changing the state. Another way would be to do the following:

var newState=[...this.state.floors];
newState.push({...});

setState(()=>({
  floors: newState
)}

2 Comments

This is kind of a mishmash of two solutions. In your first solution, you should not modify prevState.floors, which is what push does, and in your second solution you do not need to pass a callback to setState if you're producing an object that doesn't use the callback's state argument.
Thanks! Did not now that I was not allowed to modify the prevState. Now when you pointed it out I can see the reason for it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.