Визуализация объектов в списке в React - PullRequest
0 голосов
/ 30 марта 2020

Я хочу получить список компаний на странице. Я утешил входящие данные просто для уверенности, и это выглядит следующим образом

  "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": "56407787-472f-44c9-b726-189798c7e217",
            "address": {
                "street": "test street",
                "postcode": "test 12",
                "city": "test city",
                "country": "test country"
            },
            "contact_name": "Angy",
            "contact_phone": "33333333",
            "contact_email": "angy@test.fr",
        }

Следующий компонент создает список

import React from 'react';

import { makeStyles } from '@material-ui/core/styles';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import IconButton from '@material-ui/core/IconButton';
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import EditIcon from '@material-ui/icons/Edit';

const useStyles = makeStyles((theme) => ({
    root: {
        flexGrow: 1,
        maxWidth: 752,
    },
    demo: {
        backgroundColor: theme.palette.background.paper,
    },
    title: {
        margin: theme.spacing(4, 0, 2),
    },
}));

function generate(props) {
    return props.data.results.map((com) =>
        <ListItem key={com.id}>
            <ListItemText primary={com.name}/>
            <IconButton edge="end" aria-label="edit">
                <EditIcon />
            </IconButton>
        </ListItem>
    )}

const Company = (props) => {
    const classes = useStyles();

    // console.log('data is ', props.data.results)

    return (
        <div className={classes.root}>
            <Grid container spacing={2}>
                <Grid item xs={12} md={6}>
                    <Typography variant="h6" className={classes.title}>
                        company list
                    </Typography>
                    <div className={classes.demo}>
                        <List> {generate(props)} </List>
                    </div>
                </Grid>
            </Grid>
        </div>
);
};

export default Company;

Следующий компонент отображает список:

import React from "react";
import axios from 'axios';

import Company from "./Company";

class CompanyList extends React.Component {

    state = {
        companies: []
    }

    componentDidMount() {
        axios.get('http://127.0.0.1:8000/companies')
            .then(res => {
                this.setState({
                    companies: res.data
                    });
                console.log(res.data)
            })
    }

    render() {
        return (
            <Company data={this.state.companies}/>
        )
    }
}

export default CompanyList;

Я получаю сообщение об ошибке:

TypeError: Cannot read property 'map' of undefined

Я новичок в ReactJS и, вероятно, застрял с этой ошибкой. Что я тут не так делаю?

Ответы [ 3 ]

1 голос
/ 30 марта 2020

Ваше начальное состояние имеет companies, который является пустым массивом, а ваш res.data является объектом. Изначально в пустом массиве нет results. Из-за асинхронного вызова вы должны проверить, существует ли results. Это (props.data.results||[]) может решить вашу проблему. В основном это говорит, если есть results используйте его, иначе используйте пустой массив.

0 голосов
/ 30 марта 2020

Как и то, что вы видите, это изначально пустой массив при первом рендеринге, чем вложенный dict (он же объект) во втором рендере, но вы обрабатываете его так, как будто это просто вложенный объект.

Я не знаю, что именно вам нужно (рендеринг пустого списка, не рендеринг списка вообще, передача объекта / массива и т. Д. c.). Вот простое исправление, которое вы можете сделать, чтобы props.data всегда был определенным вложенным объектом:

class CompanyList extends React.Component {

    state = {
        companies: { results: [] }
    }
// ...
0 голосов
/ 30 марта 2020

Вы не передаете состояние ребенку, которому необходимо использовать данные компаний (например, из компонента CompanyList в функцию вашей компании https://reactjs.org/docs/state-and-lifecycle.html

Либо используйте управление состоянием (Redux например), чтобы связать реквизиты вашей компании с состоянием CompanyList или создать контекст и объединить с помощью ловушки useContext https://reactjs.org/docs/hooks-reference.html#usecontext

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...