0

Either fails to compile defining variables inside componentDidMount. I did a bunch of dozens of other ways. None seems to work for my particular piece of code. I think reading is better than trying to explain.

import React from 'react';
import { connect } from './api';
import './App.css';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      giphy: []
    }
  }

  componentDidMount(){
    connect(message => {
      this.setState({
        giphy: message
      })
    });
    var Items = this.state.giphy.map(function(gif){ // items is not defined.
      return <li>{gif}</li>;
    })
  }

  render () {
      return (
        <div className=".App-logo">
            <ul>
              { Items } // I wanted to show all items inside the array of objects.
            </ul>

            <ul className=".App-logo"> 
            // the following method works. We need to make sure to check for this conditions or wont work
              {this.state.giphy && this.state.giphy.length > 0   &&
                <img src={ this.state.giphy[2].images.original.url}
                alt="giphy.com animations"/>}
            </ul>
      </div>
    )
  }
}

If I remove the items, it will show the 2nd item in the state. Can you help to show all in the state?

enter image description here

2
  • You need to use the callback on setState, your array is not populated. `setState({}, () => { map state here}). Commented Sep 21, 2019 at 22:29
  • Hi staminna, check my solution and let me know if tha helps. Commented Sep 22, 2019 at 13:01

2 Answers 2

2

Instead of creating a variable in componentDidMount which cannot be used inside of render method, you can directly map your state in render method.

<ul>
   //This will show only `bitly_gif_url`
   {Array.isArray(this.state.giphy) && this.state.giphy.map(gif => <li>{gif.bitly_gif_url}</li>) } 
</ul>

Note: Your giphy array contains number of objects. From each object I have shown only bitly_gif_url using {gif.bitly_gif_url}, if you need to show any other item from your object you can change it's key.

You can show mutltiple item's at a time also,

<ul>
   //This will show `bitly_gif_url` and `embed_url` at a time
   {Array.isArray(this.state.giphy) && this.state.giphy.map(gif => <li>{gif.bitly_gif_url} {gif.embed_url}</li>) } 
</ul>
Sign up to request clarification or add additional context in comments.

1 Comment

@DanielSmith, sure will look into it.
0

As you have defined Items inside your componentDidMount function it have a functional scope and will not be available inside render function what you can do is return the items from a function. So now your code will look something like

import React from 'react';
import { connect } from './api';
import './App.css';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      giphy: []
    }

  }

  componentDidMount(){
    connect(message => {
      this.setState({
        giphy: message
      })
    });
  }

  getItems() {
    return this.state.giphy.map(function(gif){
      return <li>{gif}</li>;
    })
  }

  render () {
      return (
        <div className=".App-logo">
            <ul>
              { this.getItems() } // I wanted to show all items inside the array of objects.
            </ul>

            <ul className=".App-logo"> 
            // the following method works. We need to make sure to check for this conditions or wont work
              {this.state.giphy && this.state.giphy.length > 0   &&
                <img src={ this.state.giphy[2].images.original.url}
                alt="giphy.com animations"/>}
            </ul>
      </div>
    )
  }
}

2 Comments

Objects are not valid as a React child (found: object with keys {type, id, slug, url, bitly_gif_url, bitly_url, embed_url, username, images}). If you meant to render a collection of children, use an array instead.
as gif inside the map function is an object you need to replace {gif} with {<img src={gif.embed_url} />} i guess you get the gist.

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.