1
votes

Afficher la liste des données dans l'interface utilisateur du matériau du composant ReactJS

J'essaye de montrer une liste de films utilisant redux et material ui.

FilmsService:

import React , { Component }from 'react';
import PropTypes from 'prop-types';
import {makeStyles, withStyles} from '@material-ui/core/styles';
import {getAllFilms} from "../store/actions/FilmActions";
import Button from '@material-ui/core/Button';
import Card from "@material-ui/core/Card/Card";
import CardActionArea from "@material-ui/core/CardActionArea/CardActionArea";
import CardMedia from "@material-ui/core/CardMedia/CardMedia";
import CardContent from "@material-ui/core/CardContent/CardContent";
import Typography from "@material-ui/core/Typography/Typography";
import CardActions from "@material-ui/core/CardActions/CardActions";
import connect from "react-redux/es/connect/connect";
import { withRouter } from 'react-router-dom';

const useStyles = makeStyles({
    card: {
        maxWidth: 345,
    },
});

class FilmsCard extends Component {


    componentDidMount () {
        const {dispatch} = this.props;
        dispatch(getAllFilms());
    }

    constructor(props) {
        super(props);
        this.state = {
            change: ''
        };
    }

    render() {
        const films = this.props.films || [];
        return (
            <Card>
                {films.map(film => {
                    return(
                    <CardActionArea>
                        <CardMedia
                            component="img"
                            alt="Contemplative Reptile"
                            height="140"
                            image="/static/images/cards/contemplative-reptile.jpg"
                            title="Contemplative Reptile"
                        />
                        <CardContent>
                            <Typography gutterBottom variant="h5" component="h2">
                                {film.show ? film.show.name : film.name}
                            </Typography>
                            <Typography variant="body2" color="textSecondary" component="p">
                                {film.show ? film.show.name : film.name}
                            </Typography>
                        </CardContent>
                    </CardActionArea>
                        )})}
                <CardActions>
                    <Button size="small" color="primary">
                        Share
                    </Button>
                    <Button size="small" color="primary">
                        Learn More
                    </Button>
                </CardActions>
            </Card>
        );
    }
}

FilmsCard.propTypes = {
    classes: PropTypes.object.isRequired,
};

const mapStateToProps = (state) => {
    return {
        films : state.filmreducer
    };
}
const connectedVendorPage = withRouter(connect(mapStateToProps, null, null, {
    pure: false
})(withStyles(useStyles)(FilmsCard)));
export { connectedVendorPage as FilmsCard };

FilmAction:

   const initialState = { films: [] }
export function filmreducer(state = initialState, action) {
    switch (action.type) {
        case 'GET_FILMS':
            console.log(action);
            return{
                ...state,
                films : action.payload.data

            };
        case 'GET_FILMS_BY_NAME':
            return{
                ...state,
                films : action.payload.data

            };
        default:
            return state
    }
}

FilmReducer:

export function getAllFilms() {
    return dispatch => {
        FilmServices.getAllFilms()
            .then((response) => {
                if (response) {
                    dispatch(GET_FILMS(response));
                }
            })
    }
}


0 commentaires

3 Réponses :


0
votes

Dans la méthode render (), supprimez cette ligne const {films} = this.props.films; et essayez ceci: const films = this.props.films || []; et aussi, veuillez supprimer console.log (this.props.films) dans le constructeur. Mettez à jour FilmAction avec ceci:

export function getAllFilms() {
    return dispatch => {
        return FilmServices.getAllFilms()
            .then((response) => {
                if (response) {
                    dispatch(GET_FILMS(response));
                }
            })
    }
}


7 commentaires

J'ai eu cette erreur maintenant: TypeError: Impossible de lire la propriété 'length' de undefined


pouvez-vous également indiquer le numéro de la ligne d'erreur? Vous n'obtenez de longueur dans aucun des codes ci-dessus.


J'ai eu l'erreur lorsque j'appelle dans la méthode render ().


Tout d'abord, supprimez componentWillMount () car il est obsolète et vous ne devriez pas l'utiliser. Deuxièmement, obtenez-vous des journaux dans votre console après componentDidMount ()?


Non, je ne reçois aucun journal! seules erreurs: l'erreur ci-dessus s'est produite dans le composant , Uncaught TypeError: Impossible de lire la propriété 'map' de undefined


Je pense que le problème n'est pas dans le composant maintenant. La seule chose que vous devez changer dans le composant FilmsCard est const {films} = this.props.films; ce que vous avez déjà fait. Mettez à jour votre question avec le dernier code de composant FilmsCard et fournissez également le code FilmReducer complet.


C'est bizarre maintenant car même si this.props.films est nul, les films const devraient être un tableau vide. Changez le code FilmAction comme je l'ai mentionné dans la réponse mise à jour et fournissez le code GET_FILMS () dans votre réponse.



1
votes

@Muhammad Awais J'ai changé mon render () comme ceci et cela a fonctionné:

render() {
    const { classes } = this.props;
    const { films } = this.props.films;

    return (
        <Card className={classes.card}>
            {films.map(film => {
                return(
                    <CardActionArea>
                        <CardMedia
                            className={classes.media}
                            component="img"
                            alt="Contemplative Reptile"
                            height="140"
                            image="http://static.tvmaze.com/uploads/images/medium_portrait/168/421041.jpg"
                            title="Contemplative Reptile"
                        />
                        <CardContent>
                            <Typography gutterBottom variant="h5" component="h2">
                                {film.show ? film.show.name : film.name}
                            </Typography>
                            <Typography variant="body2" color="textSecondary" component="p">
                                {film.show ? film.show.name : film.name}
                            </Typography>
                        </CardContent>
                    </CardActionArea>
                )})}
            <CardActions>
                <Button size="small" color="primary">
                    Share
                </Button>
                <Button size="small" color="primary">
                    Learn More
                </Button>
            </CardActions>
        </Card>
    );
}

}


0 commentaires

1
votes

Aussi en changeant cette partie du code a fonctionné pour moi:

 const styles = theme => ({
        card: {
            maxWidth: 345,
        },
        media: {
            height: 50,
        },
    });

changé en ceci:

 const useStyles = makeStyles({
        card: {
            maxWidth: 345,
        },
    });


0 commentaires