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})
}))
imjared
  • 19,492
  • 4
  • 49
  • 72
user3637804
  • 167
  • 2
  • 2
  • 10

9 Answers9

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 });
imjared
  • 19,492
  • 4
  • 49
  • 72
  • Simple and works great, thank you. Although whats with the three periods, why is that required? – user3637804 Sep 06 '18 at 15:04
  • 1
    It was a little weird for me to wrap my head around but the `...` is part of a concept called "destructuring": https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment – imjared Sep 06 '18 at 15:38
  • best meaningful coding. – Aboobakkar P S Mar 13 '20 at 04:20
5

In hooks form u may use

setState((prevVals) => [...prevVals,newVals])
Yog Sharma
  • 164
  • 2
  • 9
3

For now, the best possible and simplest way is

  this.setState(previousState => ({
      floors: [...previousState.floors, {"value": value.floorName}]
  }));
Hemadri Dasari
  • 32,666
  • 37
  • 119
  • 162
  • i got error TypeError : Invalid attempt to spread non-iterable instance – Ray Coder Sep 10 '19 at 15:27
  • 1
    @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. – amitsin6h Jan 20 '20 at 17:31
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] });
})
Abdul Ahmad
  • 9,673
  • 16
  • 64
  • 127
0

You can use

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

in order to use set state.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Aditya Kuppili
  • 146
  • 1
  • 4
  • 1
    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. – user3637804 Sep 06 '18 at 14:56
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})
Bradey Whitlock
  • 201
  • 1
  • 6
0
const { floors } = this.state;

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

// Set state
this.setState({ floors });
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>
Dharman
  • 30,962
  • 25
  • 85
  • 135
Proau
  • 53
  • 3
-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
)}
Dan Mehlqvist
  • 309
  • 2
  • 5
  • 1
    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. – user229044 Sep 06 '18 at 15:45
  • 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. – Dan Mehlqvist Sep 06 '18 at 18:38