Невозможно отобразить массив из состояния внутри моего компонента, когда он исходит из ловушки - PullRequest
0 голосов
/ 30 апреля 2020

Вопрос: Почему я не могу отобразить массив из состояния внутри моего компонента?

Фон:

  1. Компонент успешно отправляет вызов API при монтировании, используя React.useEffect().

  2. Компонент не будет отображать массив для возврата дочерних компонентов в таблицу. (но фиктивные данные работают)

  3. При проверке того, что доступно в компоненте, выясняется, что фиктивные данные stati c и фактические данные о полном состоянии одинаковы в структура и доступны.

консольный журнал для обоих массивов

ObservationList.js:45 (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
ObservationList.js:46 (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

Однако, когда я пытаюсь передать observations вместо rows к функции карты внутри return() Я получаю сообщение об ошибке.

TypeError: Cannot read property 'map' of null

Отлично работает при передаче фиктивных данных.

Файл компонента:

import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux'

import Link from '@material-ui/core/Link';
import { makeStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';

import { requestAllObservations } from "./actions";
import Title from '../Title/Title';

const useStyles = makeStyles((theme) => ({
  seeMore: {
    marginTop: theme.spacing(3),
  },
}));

// // Dummy data that works
function createData(_id, date, type, severity, assetCompany, status) {
  return { _id, date, type, severity, assetCompany, status };
}
const rows = [
  createData(0, '16 Mar, 2019', 'Exposure', 'Medium', 'Pipeline Co', 'New'),
  createData(1, '16 Mar, 2019', 'Leak', 'Critical', 'Pipeline Co', 'New'),
  createData(2, '16 Mar, 2019', 'Debris', 'low', 'Pipeline Co', 'New'),
  createData(3, '16 Mar, 2019', 'Debris', 'Medium', 'Pipeline Co', 'New'),
  createData(4, '16 Mar, 2019', 'Exposure', 'Medium', 'Pipeline Co', 'New'),
  createData(5, '16 Mar, 2019', 'Debris', 'Medium', 'Pipeline Co', 'New'),
  createData(6, '16 Mar, 2019', 'Leak', 'Critical', 'Pipeline Co', 'New'),
  createData(7, '16 Mar, 2019', 'Debris', 'low', 'Pipeline Co', 'New'),
  createData(8, '16 Mar, 2019', 'Debris', 'Medium', 'Pipeline Co', 'New'),
  createData(9, '16 Mar, 2019', 'Exposure', 'Medium', 'Pipeline Co', 'New')
];
// //

export const ObservationList = (props) => {

  const classes = useStyles();

  const handleRefresh = (e) => {
    e.preventDefault()
    console.log(rows)
    console.log(observations)
  }

  const observations = useSelector(state => state.observations.observations)
  const token = useSelector(state => state.auth.token)
  const dispatch = useDispatch()

  useEffect(() => {
    dispatch(requestAllObservations(token))
  }, [false])

  return (
    <React.Fragment>
      <Title>Observations</Title>
      <Table size="small">
        <TableHead>
          <TableRow>
            <TableCell>Date</TableCell>
            <TableCell>Type</TableCell>
            <TableCell>Severity</TableCell>
            <TableCell>Company</TableCell>
            <TableCell align="right">Status</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {rows.map((row) => (
            <TableRow key={row._id}>
              <TableCell>{row.createdAt}</TableCell>
              <TableCell>{row.type}</TableCell>
              <TableCell>{row.severity}</TableCell>
              <TableCell>{row.assetCompany}</TableCell>
              <TableCell align="right">{row.status}</TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
      <div className={classes.seeMore}>
        <Link color="primary" href="#" onClick={handleRefresh}>
          refresh
        </Link>
      </div>
    </React.Fragment>
  );
}

export default ObservationList

1 Ответ

0 голосов
/ 30 апреля 2020

Похоже, что ваш state.observations.observations равен нулю до тех пор, пока ваш запрос не завершится.

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

  useEffect(() => {
    dispatch(requestAllObservations(token))
  }, [false])

  if(!observations) return 'Loading...'      

  return (
  ... (rest of return block)

Или вы можете исправить это, защитив от ложного значения, прежде чем отобразить его.

      {rows && rows.map((row) => (
        <TableRow key={row._id}>
          <TableCell>{row.createdAt}</TableCell>
          <TableCell>{row.type}</TableCell>
          <TableCell>{row.severity}</TableCell>
          <TableCell>{row.assetCompany}</TableCell>
          <TableCell align="right">{row.status}</TableCell>
        </TableRow>
      ))}

Или вы можете исправить это, сделав наблюдения имеют по умолчанию пустой массив, если он ложный. Если вы используете это, вы можете определить пустой массив 'stub' вне компонента и использовать его вместо [] внутри компонента. Таким образом, значение по умолчанию не будет изменять ссылки при каждом повторном рендеринге.

const observations = useSelector(state => state.observations.observations) || []
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...