首页 > 解决方案 > 如何在 ReactJS 中映射对象

问题描述

我有 mainPrice 对象:

client_type: "individual"
large_car: {100: "3", 200: "2.5"}
medium_car: {100: "3", 200: "2.5"}
small_car: {100: "2.5", 200: "2.5"}
x_large_car: {100: "3", 200: "2.5"}
xx_large_car: {100: "3", 200: "2.5"}

我要做的是在输入框中显示每种类型的汽车。所以基本上我正在尝试映射它。例如 small_car:

<td>
            {Object.keys(mainPrice.small_car).map((key) => (
              <tr>
                <label>{key} miles: </label>
                <InputPrice
                  mainPricePosts={mainPrice.small_car[key]}
                  handleChange={handleChange}
                />
              </tr>
            ))}
          </td>

但我收到一个错误TypeError: Cannot convert undefined or null to object但我不明白这个错误的原因。你能看看吗?

编辑:所以很多人说问题不在于地图,这就是为什么我想更多地解释代码的原因。因此,在我的父组件上,我调用 API 来获取数据,然后用这些数据设置 MainPrice。最后,就是这个对象:

client_type: "individual"
    large_car: {100: "3", 200: "2.5"}
    medium_car: {100: "3", 200: "2.5"}
    small_car: {100: "2.5", 200: "2.5"}
    x_large_car: {100: "3", 200: "2.5"}
    xx_large_car: {100: "3", 200: "2.5"}

因此,我将此数据作为道具发送到当前组件,我尝试将这些数据显示到文本框中。

所以这里是组件:

const PricePostsIndividual = ({ mainPrice }) => {
  console.log({ mainPrice })
  return (
    <>
        <tbody className="price_coefficient">
          <td>
            {/* {Object.keys(mainPrice.small_car).map((key) => (
              <tr>
                <label>{key} miles: </label>
                <InputPrice
                  mainPricePosts={mainPrice.small_car[key]}
                  handleChange={handleChange}
                />
              </tr>
            ))} */}
          </td>
          
        </tbody>
    </>
  );
};

export default PricePostsIndividual;

如您所见,我评论了 iside of 并且 mainProce 在这种情况下是正确的。

和父组件:

export default function PriceCoefficient() {
  const [mainPrice, setMainPrice] = useState({})
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(false);

  useEffect(() => {
    const fetchPosts = async () => {
      try {
        setLoading(true);
        const res = await Axios({
          method: "POST",
          url: `url`,
          headers: {
            "cache-Control": "no-cache",
            "content-Type": "application/json",
            "Access-Control-Allow-Origin": "*",
          },
        });
        if (res.status === 200) {
          setMainPrice(res.data.main_price);
        }
        setLoading(false);
      } catch (err) {
        setError(err.message);
        setLoading(false);
      }
    };
    fetchPosts();
  }, []);

  return (
    <>
      <PanelHeader size="sm" />
      <div className="content">
        <Row>
          <Col xs={12}>
            <Card>
              <CardBody>
                <h4>Main Prices</h4>
                <Table responsive>
                  <thead className="text-primary">
                    <tr>
                      <th>Small Cars</th>
                    </tr>
                  </thead>
                  <PricePostsMainPrice
                    mainPrice={mainPrice}
                    loading={loading}
                    error={error}
                  />
                </Table>
              </CardBody>
            </Card>
          </Col>
        </Row>
      </div>
    </>
  );
}

谢谢...

标签: reactjsobjectinputmapping

解决方案


问题

这里的问题是您的初始mainPrice状态是一个空对象 ( {})。

const [mainPrice, setMainPrice] = useState({});

PricePostsIndividual当您尝试抛出错误时,它最终似乎被传递到了它Object.keys(mainPrice.small_car)的位置。Cannot convert undefined or null to object

const mainPrice = {};

try {
  Object.keys(mainPrice.small_car);
  console.log('no error thrown');
} catch(error) {
  console.error(error.message);
}

解决方案

使用一些空值检查(保护子句)或可选链,或为嵌套状态提供回退值(Nullish Coalescing)以映射到 JSX。

const mainPrice = {};

try {
  // Null check/guard clause
  mainPrice.small_car && Object.keys(mainPrice.small_car);
  
  // Nullish Coalescing to provide fallback
  Object.keys(mainPrice.small_car ?? {});
  
  console.log('no error thrown');
} catch(error) {
  console.error(error.message);
}

我建议如下:

const PricePostsIndividual = ({ mainPrice = {} }) => { // provide initial value
  return (
    <>
      <tbody className="price_coefficient">
        <td>
          // Use Object.entries to get array of key-value pairs
          // provide fallback for mainPrice.small_car
          {Object.entries(mainPrice.small_car ?? {}).map(([key, value]) => (
            <tr>
              <label>{key} miles: </label>  // render key
              <InputPrice
                mainPricePosts={value}      // render value
                handleChange={handleChange} // ensure this handler is defined!!
              />
            </tr>
          ))}
        </td>
      </tbody>
    </>
  );
};

推荐阅读