【问题标题】:How to map object in ReactJS如何在 ReactJS 中映射对象
【发布时间】:2021-09-16 20:15:39
【问题描述】:

我有 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>
    </>
  );
}

谢谢...

【问题讨论】:

  • 假设你到处使用snake_case,mainPrice是这样还是应该是main_price
  • 试试这个 --> Object.keys(mainPrice?.small_car || {})
  • 可能 mainPrice 在调用此函数时没有完整的数据。使用 console.log 检查,如果您仍然需要帮助,请添加更多代码。
  • 我看不出问题使用此代码可能问题出在其他地方并在这里体现出来。请尝试更新您的问题以包含Minimal, Complete, and Reproducible Code Example
  • @Prusdrum maiinPrice 是我在问题中给出的对象。我通过获取数据来实现。

标签: reactjs object input mapping


【解决方案1】:
<td>
        {Object.keys(mainPrice.small_car).forEach((item) => (
          <tr>
            <label>{item} miles: </label>
            <InputPrice
              mainPricePosts={item}
              handleChange={handleChange}
            />
          </tr>
        ))}
      </td>

你不应该在这里使用 map 因为你不需要创建另一个对象。你只需要迭代。所以,最好使用 foreach。

检查项目对象,看看你需要什么。

【讨论】:

  • forEach 不返回结果,因此它会将其视为未定义的集合
  • Array.prototype.forEach 是一个无效返回,这将在 React 中失败。
【解决方案2】:

我不认为问题出在对象上,也许错误指的是另一个问题。

let object = {
  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" }
};

class App extends React.Component {
  render() {
    return (
      <div>
        {Object.keys(object.small_car).map((key) => (
          <tr>
            <label>{key} miles: </label>
            <input value={object.small_car[key]} />
          </tr>
        ))}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("container"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="container"></div>

【讨论】:

  • 这是一条评论,因为它不能解决 OP 的问题。
  • 它没有修复它,因为错误不在那段代码中,实际上我在答案中指出错误在其他地方。无论如何都可以,没问题:)
  • 我编辑了这个问题 :) 也许这次更清楚了
【解决方案3】:
<td>
            parts.map((part, partIndex) => {
              <tr>
                <label>{key} miles: </label>
                <InputPrice
                  mainPricePosts={part.small_car}
                  handleChange={handleChange}
                />
              </tr>
            ))}
          </td>

【讨论】:

  • 我希望这段代码能帮助你摆脱这种情况。
  • 但不是用来映射数组吗?我其实有一个对象
  • 亲爱的,数组中有多个对象还是只有一个对象?
  • 因为 map 是对象的数组,int,string 它应该是列表而不是单个对象。
【解决方案4】:

问题

这里的问题是您的初始 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>
    </>
  );
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-13
    • 2020-09-18
    • 1970-01-01
    相关资源
    最近更新 更多