properties.map 在 map 时不是函数

properties.map is not a function when map

我收到错误“TypeError:properties.map 不是函数”,但是当我 console.log(properties) 时,我可以看到数据。谁能解释我做错了什么? 如果我删除地图代码,显然不会显示错误。是因为在渲染期间尚未定义“属性”吗?我对为什么没有定义它有点困惑,因为正如我所说,我可以看到控制台加载的数据。

import React, { Component } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { AndroidOutlined, AppleOutlined } from '@ant-design/icons';
import Tabs, { TabPane } from '@iso/components/uielements/tabs';
import Select, { SelectOption } from '@iso/components/uielements/select';
import Button from '@iso/components/uielements/button';
import PageHeader from '@iso/components/utility/pageHeader';
import Box from '@iso/components/utility/box';
import { Form, Input, Checkbox, Col, Row } from 'antd'
import LayoutWrapper from '@iso/components/utility/layoutWrapper.js';
import ContentHolder from '@iso/components/utility/contentHolder';
import IntlMessages from '@iso/components/utility/intlMessages';
import FormGeneral from './FormGeneral';
import FormDetails from './FormDetails';

import propertiesActions from '@iso/redux/properties/actions';
const Option = SelectOption;

const {
  loadFromApi,
} = propertiesActions;

export default function PropertiesPage() {

  const dispatch = useDispatch();
  React.useEffect(() => {
    dispatch(loadFromApi());
  }, [dispatch]);

  const { properties, property, isLoading } = useSelector(
    state => state.Properties
  );

  const rowStyle = {
    width: '100%',
    display: 'flex',
    flexFlow: 'row wrap',
  };
  const colStyle = {
    marginBottom: '16px',
  };
  const gutter = 16;

  // Show data
  console.log(properties);
  console.log(isLoading);

  return (
    <LayoutWrapper>
      <PageHeader>Properties</PageHeader>

      <Box>
        <Tabs defaultActiveKey="1">
          <TabPane
            tab={
              <span>
                <AppleOutlined />
                General
              </span>
            }
            key="1"
          >

          <div>
            {console.log(properties)}
            {properties.map(e =>
              <div key={e.id}>
                {e.id}
              </div>  
            )} 
          </div>

          <Row style={rowStyle} gutter={gutter} justify="start">
            <Col md={12} sm={12} xs={24} style={colStyle}>
              <Box>
                <FormGeneral />
              </Box>
            </Col>
          </Row>

          </TabPane>
          <TabPane
            tab={
              <span>
                <AndroidOutlined />
                Tab 2
              </span>
            }
            key="2"
          >
            <FormDetails />
          </TabPane>
        </Tabs>
      </Box>
    </LayoutWrapper>
  );
}

更新:

properties 一开始是空对象

如果尝试properties?.map怎么办,所以如果是undefined就不映射了,等到真正拿到数组。因为我对 redux 了解不多,但是从我从你的代码中读到的,我知道你是异步获取属性的。

默认 propertiesundefined.map 无法与 undefined 一起使用。尝试使用:

  const { properties = [], property, isLoading } = useSelector(
    state => state.Properties
  );

可以扩展答案并更改 initialState,但需要您的 reducer 代码。

在你映射属性之前,你应该检查它是否是未定义的,因为反应中状态对象的初始值是未定义的,我认为如果你将在你的控制台中滚动你应该看到一个未定义的打印到控制台

<div>
        {console.log(properties)}
        {properties !== undefined ? properties.map(e =>
          <div key={e.id}>
            {e.id}
          </div>  
        ): null} 
      </div>

事实上,对象已定义但为空,我必须检查长度

<div>
    {console.log(properties)}
    {properties.length > 1 ? properties.map(e =>
      <div key={e.id}>
        {e.id}
      </div>  
    ): null} 
  </div>

这样做解决了问题。