我正在从服务器获取自动完成选项,它完美地获取,并且它显示已经从获取的数据中选择回来的选项,我现在面临的错误是,每当我试图删除或移除一个芯片标签时,整个页面都会崩溃,控制台日志向我显示以下警告:
MUI:提供给自动完成的值无效。没有一个选项与[{"catName":{"catName":"fbkljfmb,"}},{"catName":{"catName":"kj.sfbalkdfb"}},{"catName":{"catName":"jkflnbr.efb"}},{"catName":{"catName":"rfbsdrfbertherth"}}]
匹配。您可以使用isOptionEqualToValue
属性自定义相等性测试。
和这个错误:
未捕获的错误:对象作为React子级无效(找到:如果你想呈现一个子元素的集合,请使用数组。
自动补全组件代码如下:
export default function SelectPostsCatsOptions({onBlur, selectedCategories, setSelectedCategories, readOnly, value}) {
const [postsCats, setPostsCats] = useState([]);
const [loading, setLoading] = useState(true);
// FETCH THE CATEGORIES FROM THE DATABASE
useEffect(() => {
const getPostsCats = async () => {
const res = await axios.get("/postscategories");
setPostsCats(res.data);
setLoading(false);
console.log("Categories Are:", res.data);
};
getPostsCats()
}, []);
// END OF FETCH THE CATEGORIES FROM THE DATABASE
return (
<div>
<Autocomplete
readOnly={readOnly}
multiple
disablePortal
id="postsCats"
getOptionLabel={(postsCats) => `${postsCats.catName}`}
options={postsCats}
isLoading={loading}
loadingText="Loading categories..."
maxWidth={false}
disableGutters
isOptionEqualToValue={(option, value) => option.catName === value.catName}
noOptionsText={"No Available Options"}
renderOption={(props, postsCats) => (
<li
{...props}
key={postsCats.id}
style={{ f… }}>
{postsCats.catName}
</li>
)}
value={selectedCategories.map((catName) => ({ catName }))}
// THE TAGS SELECTED
renderTags={(value, getTagProps) =>
value.map((option, index) => (
<Chip
key={option.id}
label={option.catName}
{...getTagProps({ index })}
style={{…}}
/>
))
}
// END OF THE TAGS SELECTED
renderInput={(params) => <TextField
readOnly={readOnly}
{...params}
placeholder="Categories"
InputLabelProps={{ style: { … } }}
sx={{…}}
// THE RIGHT END ICON
InputProps={{
style: {…},
...params.InputProps,
endAdornment: (
<React.Fragment>
{loading ? <CircularProgress color="inherit" size={20} /> : null}
{params.InputProps.endAdornment}
</React.Fragment>
),
}}
// END OF THE RIGHT END ICON
/> }
onChange={(event, newSelectedCategories) => setSelectedCategories(newSelectedCategories)}
/>
</div>
);
}
自动完成功能使用页面:
import SelectPostsCatsOptions from "../../components/autocomplete/SelectPostsCatsOptions";
export default function PostInfo() {
const [categories, setCategories] = useState([]);
const [selectedCategories, setSelectedCategories] = useState([]);
const [postInfoPageUpdateMode, setPostInfoPageUpdateMode] = useState(false);
// TO FETCH DATA FROM THE DATABASE
useEffect(() => {
// TO FETCH POST
const getPost = async () => {
try {
const res = await axios.get("/posts/" + path);
setPost(res.data);
setCategories(res.data.categories);
setIsLoading(false);
// HANDLING ERROR
} catch (err) {
}
// END OF HANDLING ERROR
};
getPost()
}, [path]);
// END OF TO FETCH DATA FROM THE DATABASE
// HANDLE THE DATA TO SUBMIT
const handleUpdate = async () => {
if (!title || !content || !photo ) {
setAlertMsg({ fail: true, success: false, msg: "All fields are required!" });
return;
} else try {
await axios.put(`/posts/${post._id}`, {
username:user.username,
title,
content,
photo,
categories: selectedCategories.map(cat => cat.catName),
});
window.location.reload();
setPostInfoPageUpdateMode(false);
// HANDLING ERROR
} catch (err) {
}
// END OF HANDLING ERROR
};
// END OF HANDLE THE DATA TO SUBMIT
return (
// // POST INFO PAGE
<div className="PostInfoPage">
{/* IF THE PAGE IS LOADING SHOW CIRCULAR PROGRESS */}
{isLoading ? (
………
) : (
<>
{/* IF THE PAGE IS ON UPDATE MODE */}
{postInfoPageUpdateMode ? (
// SAVE & DISCARD BUTTON CONTAINER
<div className="PostInfoPageUpdateIconButtonContainer">
……….
</div>
// END OF SAVE & DISCARD BUTTON CONTAINER
) : (
)}
{/* END OF IF THE PAGE IS ON UPDATE MODE */}
<div className="PostInfoPageTop">
</div>
{/* POST VIEW OR EDIT CONTAINER */}
<div className="PostInfoPageBottom" dir="auto">
{/* POST FORM */}
<form className="PostInfoPageForm" dir="auto">
{/* POST INFO TITLE IMAGE UPLOAD CONTAINER */}
<div className="PostInfoPageTitleImageUploadCont">
</div>
{/* END OF POST INFO TITLE IMAGE UPLOAD CONTAINER */}
{/* POST CATEGORIES CONTAINER */}
<div className="PostInfoPagePostContentContainer">
<h3>Post Categories:</h3>
<SelectPostsCatsOptions
selectedCategories={categories}
setSelectedCategories={setSelectedCategories}
readOnly={postInfoPageUpdateMode ? false : true}
/>
</div>
{/* END OF POST CATEGORIES CONTAINER */}
</form>
{/* END OF POST FORM */}
</div>
{/* END OF POST VIEW OR EDIT CONTAINER */}
</>
)}
{/* END OF IF THE PAGE IS LOADING SHOW CIRCULAR PROGRESS */}
</div>
// // END OF POST INFO PAGE
);
}
我试图在这里做的是编辑(添加或删除所选选项)自动完成并重新提交它没有任何问题。
1.我尝试将value={selectedCategories.map((catName) => ({ catName }))}
更改为value={selectedCategories},标签中的文本消失了
1.我试着调试value
、getOptionLabel
和isOptionEqualToValue
:console.log("selectedCategories Are:", selectedCategories)
getOptionLabel={(postsCats) => {
console.log("getOptionLabel:", postsCats.catName);
return `${postsCats.catName}`;
}}
isOptionEqualToValue={(option, value) => {
console.log("isOptionEqualToValue:", option, value);
return option.catName === value;
}}
1.正如我提到的,当我使用value={selectedCategories}
时,标签芯片中的文本消失了,但它在选项列表中显示为选定的类别:
我不知道我到底哪里错了!
1条答案
按热度按时间mzsu5hc01#
你没有正确地设置选项的值。你把选项设置为一个新的对象,它的属性为
catName
,包含了原来的选项。我认为原因是解构。不如试试这个。
但这将设置值仅为
catName
,如果您想要整个postCat
,则应使用selectedCategories
数组