Search code examples
javascriptreactjsreact-domreact-state-management

React DOM not updating even though the state and props have


I am looking to use map() to iterate over and add to my DOM in react, however, my DOM is not updating.

I think the everything is syntactically written ok, so I am really stumped by this. Any help you can give me I'd really appreciate, thanks.

App.js

class App extends Component {
...
    searchThis() {
        axios.get("/getYoutube", {params: {searchString: this.state.searchVal}}).then(({ data }) => {
            this.setState({
                youtubeVids: data.resp.items
            })
        })
    }

    render() {
        if (this.state.youtubeVids.length > 0) {
            console.log(this.state.youtubeVids[0].snippet.thumbnails.default.url)

            return (
                <div className="app-container">
                    <div className="app-header">
                        <h1>YouTube API App</h1>
                    </div>
                    <div className="app-body">
                        <div className="each-body-section">
                            <SearchResults 
                                youtubeVids = {this.state.youtubeVids}
                            />
                        </div>
                    </div>
                </div>
            );
        }
    }
}

export default App;

Right now I am bringing server api results into the frontend using setState() and Axios through the searchThis() method, which I am logging and seeing successfully in my console from my props. However in SearchResults.js, nothing is updating in the DOM SearchResults.js

import React from "react";

const SearchResults = props => {
    console.log("props in search ", props.youtubeVids)

    return (
    <div className="each-body-section video-container">
            {props.youtubeVids.map((video) => {
                <div key={video.id.videoId}>
                    <div className="video-title">
                        <h2>{video.snippet.title} </h2>
                    </div>
                    <div>
                        <img src={video.snippet.thumbnails.high.url} />
                    </div>
                    <div>
                        <p>{video.snippet.description}</p>
                    </div>
                </div>
            })}
    </div>
    )
}

export default SearchResults

Solution

  • Well, its because you are trying to map an empty array in SearchResults.js

    Change SearchResults.js to the code below and try again:

    import React, { Component } from 'react';
    
    class SearchResults extends Component {
    
        render() {
            console.log(this.props.youtubeVids);
            if (this.props.youtubeVids.length > 0) {
                var youtubeVidsMap = this.props.youtubeVids.map((video) => <div key={video.id.videoId}>
                    <div className="video-title">
                        <h2>{video.snippet.title} </h2>
                    </div>
                    <div>
                        <img src={video.snippet.thumbnails.high.url} />
                    </div>
                    <div>
                        <p>{video.snippet.description}</p>
                    </div>
                </div>);
    
            }
            return (
    
                <div className="each-body-section video-container">
                    {youtubeVidsMap}
                </div>
            );
        }
    }
    
    export default SearchResults;
    

    If you want to use stateless component, the code below should work:

    import React from "react";
    
    const SearchResults = props => {
    
        if (props.youtubeVids.length > 0) {
            var youtubeVidsMap = props.youtubeVids.map((video) => <div key={video.videoId}>
                <div className="video-title">
                    <h2>{video.snippet.title} </h2>
                </div>
                <div>
                    <img src={video.snippet.thumbnails.high.url} />
                </div>
                <div>
                    <p>{video.snippet.description}</p>
                </div>
            </div>);
    
        }
    
        return (
        <div className="each-body-section video-container">
                {youtubeVidsMap}
        </div>
        )
    }
    
    export default SearchResults