javascript 自动完成无法编辑

k2arahey  于 2023-03-28  发布在  Java
关注(0)|答案(1)|浏览(148)

我正在从服务器获取自动完成选项,它完美地获取,并且它显示已经从获取的数据中选择回来的选项,我现在面临的错误是,每当我试图删除或移除一个芯片标签时,整个页面都会崩溃,控制台日志向我显示以下警告:
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.我试着调试valuegetOptionLabelisOptionEqualToValue
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}时,标签芯片中的文本消失了,但它在选项列表中显示为选定的类别:

我不知道我到底哪里错了!

mzsu5hc0

mzsu5hc01#

你没有正确地设置选项的值。你把选项设置为一个新的对象,它的属性为catName,包含了原来的选项。我认为原因是解构。

value={selectedCategories.map((catName) => ({ catName }))}

不如试试这个。

value={selectedCategories.map(({ catName }) => catName)}

但这将设置值仅为catName,如果您想要整个postCat,则应使用selectedCategories数组

value={selectedCategories}

相关问题