0

My initial state varies depending on how many items I get from the API call.

So basically sometimes it looks like this:

  class MyComponent extends Component {
    state = {
     activeItem0: '',
     activeItem1: '',
     activeItem2: '',
     activeItem3: '',
   } 
    ...

and some times it might look like this depending on the data returned by the database.

  class MyComponent extends Component {
    state = {
     activeItem0: '',
     activeItem1: '',
     activeItem2: '',
     activeItem3: '',
     activeItem4: '',
     activeItem5: '',
   } 
    ...

Is there a way to set the initial state keys dynamically?

here's what I have so far:

class MyComponent extends Component {
  state = {
   activeItem0: '',
   activeItem1: '',
   activeItem2: '',
   activeItem3: ''
 }

 // Set the value for each product on the store
  handleItemClick = (e, { name, children }) => this.setState({[e.target.name]: children })

 let buttonGroup = _.times(products.length, i => (
    <Button.Group>
       <Button
         name={`activeItem${i}`}
         active={this.state[`activeItem${i}`] === 'Val1'}
         onClick={this.handleItemClick}
        >
          Val1
       </Button>

       <Button
         name={`activeItem${i}`}
         active={this.state[`activeItem${i}`] === 'Val2'}
         onClick={this.handleItemClick}>
         Val2
        </Button>

        <Button
         name={`activeItem${i}`}
         active={this.state[`activeItem${i}`] === 'Val3'}
         onClick={this.handleItemClick}>
          Val3
        </Button>
      </Button.Group>
    )

 render() {
  return(
     <div>
       <Grid container>{selectSizeInSideBar}</Grid>
     </div>
    )
   }
  }

So the issue is that if products.length returned by the DatabBase is 4 I should have in my initial state like this

   state = {
    activeItem0: '',
    activeItem1: '',
    activeItem2: '',
    activeItem3: ''
   }

but if my products.length returned by the DatabBase is 6 then my initial state should look like this:

   state = {
    activeItem0: '',
    activeItem1: '',
    activeItem2: '',
    activeItem3: ''
    activeItem4: ''
    activeItem5: ''
   } 
AziCode
  • 2,510
  • 6
  • 27
  • 53
  • 1
    I suggest to make API call in componentDidMount and then use setState – kenodek Apr 23 '19 at 15:03
  • That's not related to my question – AziCode Apr 23 '19 at 15:05
  • What decides how many items you need? When do you need 3 and when do you need 5? – Daan Apr 23 '19 at 15:05
  • It depends on the result of my GET API call, I sometimes receive 3, sometimes 5 and sometimes 7 – AziCode Apr 23 '19 at 15:06
  • Depends, how do you determine what it should be? From props passed into the component when it's created, or some time after? – Dominic Apr 23 '19 at 15:07
  • 1
    So where is your API call? – kenodek Apr 23 '19 at 15:08
  • @Dominic yes, from props passed into the component – AziCode Apr 23 '19 at 15:08
  • @DominikTargosz their suggestion was right then. Do the API call in `componentDidMount` and pass the preferred object to the state. – Daan Apr 23 '19 at 15:10
  • @Daan I already have the result of the API call available for the component to use. The API call is done in a parent component and I get the result from the redux store – AziCode Apr 23 '19 at 15:12
  • @Daan My issue is how to determine how many keys to put in the initial state, not the values of those keys. how to dynamically set the activeItem keys – AziCode Apr 23 '19 at 15:15
  • Please provide your code and what you have tried so far. This way we can help you without having to assume what would be the solution to your problem. – Daan Apr 23 '19 at 15:15
  • @Daan yes you're correct, I'm going to edit my question – AziCode Apr 23 '19 at 15:15
  • Possible duplicate of [Reactjs setState() with a dynamic key name?](https://stackoverflow.com/questions/29280445/reactjs-setstate-with-a-dynamic-key-name) – Daan Apr 23 '19 at 15:18
  • @Daan I have edited my question with more details, and I'll check the duplicate that you mentioned – AziCode Apr 23 '19 at 15:31
  • @Daan Never mind, my code was actually working without adding those keys in the initial state... my `handleItemClick` function was actually creating the keys dynamically – AziCode Apr 23 '19 at 15:37

1 Answers1

0

You can make a method that initialize your state after your component is ready ( let's say the data of your API has been received ), so its preferrable to make this in the componentDidMount.

const initializeStateForKeys = ( products ) => {
   const fakeState = {};
   _.each( products, product => {  
     fakeState[ product.id ] = { id: product.id ,isActive: product.isActive }
   } );

   return fakeState
}

and you should use it like this:

componentDidMount(){
  API.fetchMyProducts()
  .then( response => {
    this.setState( { products: response.data.products } 
    , () => {
     this.initializeStateForKeys( this.state.products);
    }); 
   });
}
Ricardo Gonzalez
  • 1,827
  • 1
  • 14
  • 25