【问题标题】:Populate React dropdown with Axios response使用 Axios 响应填充 React 下拉列表
【发布时间】:2021-11-24 10:37:04
【问题描述】:

我在 React 中做了一个下拉菜单,我想用来自 Axios GET 调用 API 的响应来填充它。

我的 API 调用在不同的脚本上。

import DIDataService from "../services/DIService";
import React from "react";

const PresetDropDown= () => {
  const [presets, setPresets] = React.useState([]);

  React.useEffect(() => {
    async function getPresets() {
      const response = DIDataService.findAllPresets()
      .catch((e) => {
        console.log(e);
      });
      setPresets(response);
    }
    getPresets();
  }, []);

  return (
    <select>
      {presets.map(item => (
        <option
          key={item.value}
          value={item.value}
        >
          {item.label}
        </option>
      ))}
    </select>
  );
}

export default PresetDropDown;

但我在尝试映射选择的选项时遇到了一个严重的错误:

Uncaught TypeError: presets.map is not a function
    at PresetDropDown (PresetDropDown.js:19)
    at renderWithHooks (react-dom.development.js:14985)
    at updateFunctionComponent (react-dom.development.js:17356)
    at beginWork (react-dom.development.js:19063)
    at HTMLUnknownElement.callCallback (react-dom.development.js:3945)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:3994)
    at invokeGuardedCallback (react-dom.development.js:4056)
    at beginWork$1 (react-dom.development.js:23964)
    at performUnitOfWork (react-dom.development.js:22776)
    at workLoopSync (react-dom.development.js:22707)
    at renderRootSync (react-dom.development.js:22670)
    at performSyncWorkOnRoot (react-dom.development.js:22293)
    at react-dom.development.js:11327
    at unstable_runWithPriority (scheduler.development.js:646)
    at runWithPriority$1 (react-dom.development.js:11276)
    at flushSyncCallbackQueueImpl (react-dom.development.js:11322)
    at flushSyncCallbackQueue (react-dom.development.js:11309)
    at flushPassiveEffectsImpl (react-dom.development.js:23620)
    at unstable_runWithPriority (scheduler.development.js:646)
    at runWithPriority$1 (react-dom.development.js:11276)
    at flushPassiveEffects (react-dom.development.js:23447)
    at react-dom.development.js:23324
    at workLoop (scheduler.development.js:590)
    at flushWork (scheduler.development.js:545)
    at MessagePort.performWorkUntilDeadline (scheduler.development.js:157)

API 返回的 JSON 是一个数组:

[
{
"presetName": "DEFAULT",
"presetValue": "project = BD",
"id": 200001348
},
{
"presetName": "FirstTest",
"presetValue": "key = BD-1038",
"id": 200001349
},
{
"presetName": "SecondTest",
"presetValue": "key = BD-1031",
"id": 200001350
},
{
"presetName": "SecondTest",
"presetValue": "key = BD-1031",
"id": 200001351
},
{
"presetName": "SecondTest",
"presetValue": "key = BD-1031",
"id": 200001352
},
{
"presetName": "SecondTest",
"presetValue": "key = BD-1031",
"id": 200001353
},
{
"presetName": "SecondTest",
"presetValue": "key = BD-1031",
"id": 200001354
},
{
"presetName": "ThirdTest",
"presetValue": "key = BD-1039",
"id": 200001355
}
]

如何将我从 Axios 获得的 JSON 映射到下拉选项?

更新 1:

我改变了我的 useEffects 钩子来使用这样的响应:

  React.useEffect(() => {
    async function getPresets() {
      DIDataService.findAllPresets()
      .then((response) => {
        setPresets(response.data.map(({ presetName, presetValue }) => ({ label: presetName, value: presetValue })));
      })
      .catch((e) => {
        console.log(e);
      });
    }
    getPresets();
  }, []);

【问题讨论】:

  • 你在DIDataService.findAllPresets()返回什么?您是返回response.data 还是只是回复?如果你返回响应对象,你应该有一个错误
  • 不是一个答案,只是一个建议,您在 React.useEffect 中定义的名为 getPresets 的函数在这种情况下似乎没有必要。你可以将getPresets 的整个逻辑直接放在useEffect 中而不用创建函数。另外一点,由于您在 fetch 调用之外使用 setState,因此假设 DIDataService 是异步的(因为您将 getPresets 指定为异步),您的响应可能为空。如果它确实在对某个服务器进行异步调用,您应该 await 响应。

标签: javascript reactjs axios json-deserialization


【解决方案1】:

DIDataService.findAllPresets() 似乎返回了一个承诺,要么等待,要么调用 then():

DIDataService.findAllPresets().then(res => setPresets(res))
//Or
const res = await DIDataService.findAllPresets();
setPresets(res)

另外,既然你说 axios,我认为它返回的是 axios 响应,所以你必须获取数据:

DIDataService.findAllPresets().then(({data}) => setPresets(data))
//Or
const { data } = await DIDataService.findAllPresets()
setPresets(data)

【讨论】:

    【解决方案2】:
    React.useEffect(() => {
        async function getPresets() {
          // here findAllPresets will return a promise, not the data you want to manipulate
          const response = DIDataService.findAllPresets()
          .catch((e) => {
            console.log(e);
          });
          setPresets(response);
        }
        getPresets();
      }, []);
    

    这是一个正确的示例

    React.useEffect(() => {
        async function getPresets() {
          const response = await DIDataService.findAllPresets()
          .catch((e) => {
            console.log(e);
          });
          setPresets(response);
        }
        getPresets();
      }, []);
    

    React.useEffect(() => {
        function getPresets() {
          DIDataService.findAllPresets()
          .then(res => {
            setPresets(res)
          })
          .catch((e) => {
            console.log(e);
          });
        }
        getPresets();
      }, []);
    

    【讨论】:

      猜你喜欢
      • 2022-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-18
      • 2012-11-07
      • 2016-05-12
      • 2011-08-18
      • 1970-01-01
      相关资源
      最近更新 更多