为什么我收到TypeError choices.map不是函数?

时间:2019-08-11 22:05:12

标签: arrays reactjs axios material-ui menuitem

我试图用<select>将数组中的项目(选择)映射到<MenuItem>字段,我非常接近,但是遇到了TypeError choices.map is not a function错误。

const useStyles = makeStyles(theme => ({
  root: {
    display: 'flex',
    flexWrap: 'wrap',
  },
  formControl: {
    margin: theme.spacing(1),
    minWidth: 250,
  },
  selectEmpty: {
    marginTop: theme.spacing(2),
  },
}));

下面是问题所在的部分,上面只是样式。

function SimpleSelect() {
  const classes = useStyles();
  const [values, setValues] = React.useState({
    firm: '',
    infosys: '',
    spot: '',
  });
  const [choices, setChoices] = React.useState([])

    const inputLabel = React.useRef(null);
  const [labelWidth, setLabelWidth] = React.useState();

  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(
        'http://127.0.0.1:5000/form/'
      );

      setChoices({ choices: result.data })
    };
    fetchData();
  }, []);

  function handleChange(event) {
    setValues(values)
  }

return (
    <form className={classes.root} autoComplete="off">
      <FormControl className={classes.formControl}>
        <InputLabel htmlFor="firm-helper">Firm</InputLabel>
        <Select
          value={values.firm}
          onChange={handleChange}
          input={<Input name="firm" id="firm-helper" />}
        >
          {choices.map((choice, index) =>
          <MenuItem key={index} value={index} primaryText={choice} /> 
          )}
        </Select>
        </Select>
        <FormHelperText>Select a Firm</FormHelperText>
      </FormControl>
    </form>
  );
}

export default SimpleSelect;

我目前正在获取此信息:

sed-vars
  Line 39:  Effect callbacks are synchronous to prevent race conditions. Put the async function inside:

useEffect(() => {
  async function fetchData() {
    // You can await here
    const response = await MyAPI.getData(someId);
    // ...
  }
  fetchData();
}, [someId]); // Or [] if effect doesn't need props or state


我确实收到带有axios请求的数组的JSON响应。我最终还将需要每种表单handelChange(event)来向端点创建POST请求。

1 个答案:

答案 0 :(得分:1)

编辑: 我使用公共API进行了示例-您需要使组件看起来像这样。

实时演示/示例:

Edit condescending-shadow-gmn6c

SimpleSelect

import React, { useEffect, useState } from "react";
import axios from "axios";
import { makeStyles } from "@material-ui/core/styles";
import {
  FormControl,
  Select,
  FormHelperText,
  Input,
  InputLabel,
  MenuItem
} from "@material-ui/core";

const useStyles = makeStyles(theme => ({
  root: {
    display: "flex",
    flexWrap: "wrap"
  },
  formControl: {
    margin: theme.spacing(1),
    minWidth: 250
  },
  selectEmpty: {
    marginTop: theme.spacing(2)
  }
}));

function SimpleSelect() {
  const classes = useStyles();
  const [choices, setChoices] = useState([]);
  const [selectedChoice, setSelectedChoice] = useState("");

  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(
        "https://jsonplaceholder.typicode.com/todos?_limit=10"
      );
      setChoices(result.data);
    };
    fetchData();
  }, []);

  function handleChange(event) {
    setSelectedChoice(event.target.value);
  }

  return (
    <div>
      <form className={classes.root} autoComplete="off">
        <FormControl className={classes.formControl}>
          <InputLabel htmlFor="firm-helper">Firm</InputLabel>
          {/*
            PLESE CONSOLE.LOG SO YOU CAN SEE WHAT IS IN YOUR API RESPONSE!!!
          */}
          {console.log(choices)}
          <Select
            value={selectedChoice}
            onChange={handleChange}
            input={<Input name="firm" id="firm-helper" />}
          >
            {choices.map((choice, index) => (
              <MenuItem key={index} value={choice}>
                {choice.title}
              </MenuItem>
            ))}
          </Select>
          <FormHelperText>Select a Firm</FormHelperText>
        </FormControl>
      </form>
      {selectedChoice ? (
        <div>
          <h4>Selected Choice:</h4>
          <pre>{JSON.stringify(selectedChoice, null, 2)}</pre>
        </div>
      ) : (
        ""
      )}
    </div>
  );
}

export default SimpleSelect;

原始答案:

问题似乎与您最初设置choices状态的方式有关。在装入组件并等待数据到达时,您正在使用mapchoices.map(...)-根据您的初始状态设置,该字段必须为:choices.choices.map(...)

更改为choices.choices.map(...)会加载您的组件,但是在数据到达后,您将再次遇到相同的错误,这是由于您如何在choices内设置useEffect ...有关更多信息,请参见下文,但您需要将useEffect更改为:setChoices({ choices: data.results })


如果您不想使用choices.choices-您要做的就是更改:

      const [choices, setChoices] = React.useState({
        choices: [],
      })
  • 为此:
      const [choices, setChoices] = React.useState([])

如果您想继续使用choices.choices,则需要进行以下更改:

  • map来自:
  {choices.map((choice, index) =>
    <MenuItem key={index} value={index} primaryText={choice} /> 
  )}
  • 收件人:
  {choices.choices.map((choice, index) =>
    <MenuItem key={index} value={index} primaryText={choice} /> 
  )}

~~~~~~~~~~~~~ 和 ~~~~~~~~~~~~~

  • useEffect来自:
React.useEffect(() => {
 // other code here
  setChoices(result.data);
})
  • 收件人:
React.useEffect(() => {
 // other code here
  setChoices({ choices: result.data });
})

此外,正如其他人提到的那样,您需要验证results.data的内容是否可迭代,并且可以map覆盖。.