S
S
stepan1322019-05-25 22:30:49
React
stepan132, 2019-05-25 22:30:49

How to rerender a component?

Hello. I immediately apologize for the possible stupidity of the question, I'm just new to react. I decided to create a site like imdb. Here is the component that renders a particular movie:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import styled from 'styled-components';

import Preloader from '../components/Preloader/Preloader';

let FilmCardWrapper = styled.div`
    width: 100%;
    display: flex;
    justify-content: space-between;
    margin-bottom: 70px;
`
let FilmCardInfo = styled.div`
    width: 50%;
`
let FilmTitle = styled.h1`
    border-bottom: 2px solid #eee;
`
let FilmOverview = styled.p`
    border-bottom: 2px solid #eee;
    padding-bottom: 20px;
`
let GoBackBtn = styled.button`
    display: block;
    width: 200px;
    height: 40px;
    line-height: 40px;
    text-align: center;
    margin: 0 auto;
    margin-bottom: 40px;
    margin-top: 5px;
    border-radius: 4px;
    border: 3px solid #eee;
    background: none;
    cursor: pointer;
`
let SimilarFilmsWrapper = styled.div`
    
`
let SimilarFilmCard = styled.div`
    position: relative;
    width: 150px;
    height: 200px;
`
let SimilarFilmCardImg = styled.img`
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
`
let SimilarFilmCardInfo = styled.div`
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
`

class FilmPage extends Component {
    state = {
        isLoading: true
    }

    componentDidMount() {
        this.setCurrentFilm(this.props.filmId);                              <-- это место вызова функции загрузки данных
    }

    setCurrentFilm = async (id) => {
        this.setState({isLoading: true});
        let { service, setCurrentFilm } = this.props;
        let filmData = await service.getFilm(id);
        let similarFilms = await service.getSimilarFilms(id);
        setCurrentFilm({
            film: filmData,
            similar: similarFilms
        });
        this.setState({isLoading: false});
    }

    render() {
        let { film, similarFilms } = this.props.currentFilm;
        return (
            <>
                {this.state.isLoading ?
                    <Preloader /> :
                    <div>
                        <FilmCardWrapper>
                            <img src={`https://image.tmdb.org/t/p/w500${film.poster_path}`} alt="film"/>
                            <FilmCardInfo>
                                <FilmTitle>{film.title}</FilmTitle>
                                <h2>{film.tagline}</h2>
                                <FilmOverview>{film.overview}</FilmOverview>
                                <h3>Vote: {film.vote_average}</h3>
                                <h3>Votes count: {film.vote_count}</h3>
                                <h3>Release: {film.release_date}</h3>
                                <h3>Budget: {film.budget}$</h3>
                                <h3>Status: {film.status}</h3>
                            </FilmCardInfo>
                        </FilmCardWrapper>
                        <h2>Similar films</h2>
                        <SimilarFilmsWrapper>
                            {
                                similarFilms.results.map((el) => {
                                    return (
                                        <SimilarFilmCard key={el.id}>
                                            <SimilarFilmCardImg src={`https://image.tmdb.org/t/p/w500${el.poster_path}`} alt="film" />
                                            <SimilarFilmCardInfo>
                                                <h3>{el.title}</h3>
                                                <Link to={`/film/${el.id}`}>View more</Link>
                                            </SimilarFilmCardInfo>
                                        </SimilarFilmCard>
                                    )
                                })
                            }
                        </SimilarFilmsWrapper>
                    </div>
                }
                <GoBackBtn onClick={this.props.history.goBack}>Go back</GoBackBtn>
            </>
        );
    }
}

let mapStateToProps = ({ currentFilm }) => {
    return {
        currentFilm
    }
}
let mapDispatchToProps = (dispatch) => {
    return {
        setCurrentFilm: (film) => dispatch({type: 'SET_CURRENT_FILM', payload: film})
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(FilmPage);

In general, the essence of the problem: during a normal transition to the page, everything works, the component is updated, but if you click on any movie from the "similar" section, the component is not re-rendered. I checked, the id is correct, the component is simply not updated. I'm assuming it's because of component did mount, but are there any alternatives to it, or do I have to redo it somehow?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Spirin, 2019-05-25
@stepan132

componentDidUpdate(prevProps) {
  if (prevProps.filmId !== this.props.filmId) {
    this.setCurrentFilm(this.props.filmId);
  }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question