我试图用<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请求。
答案 0 :(得分:1)
编辑: 我使用公共API进行了示例-您需要使组件看起来像这样。
实时演示/示例:
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
状态的方式有关。在装入组件并等待数据到达时,您正在使用map
:choices.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
覆盖。.