我想在自动完成组件上使用onChange
事件来获取当前选定的值。
问题在于它无法按预期运行,因此当我单击以选中/取消选中值复选框时,仍未选中该复选框,但是在控制台中,我可以看到已添加了新值
此部分不起作用,以使其起作用:
value={myTempVal}
onChange={(event, newValue) => {
setMyTempVal(newValue);
console.log(newValue);
}}
在线演示: https://codesandbox.io/embed/hardcore-snowflake-7chnc?fontsize=14&hidenavigation=1&theme=dark
代码:
const [myTempVal, setMyTempVal] = React.useState([]);
<Autocomplete
open
multiple
value={myTempVal}
onChange={(event, newValue) => {
setMyTempVal(newValue);
console.log(newValue);
}}
disableCloseOnSelect
disablePortal
renderTags={() => null}
noOptionsText="No labels"
renderOption={(option, { selected }) => {
return (
<>
<Checkbox
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={selected}
/>
{option.title}
</>
);
}}
options={option2}
// groupBy={option => option.groupName}
getOptionLabel={option => option.title}
renderInput={params => (
<div>
<div>
<SearchIcon />
</div>
<TextField
variant="outlined"
fullWidth
ref={params.InputProps.ref}
inputProps={params.inputProps}
/>
</div>
)}
/>
答案 0 :(得分:1)
您需要从函数中获取donors
receivers
和options
变量。这些变量在每次渲染时都会重新创建,这意味着它们的引用在每次渲染时都会更改,并且当自动完成功能进行参考相等性检查来确定是否选择了某个选项时,他永远找不到所选的选项。
const donors = [...new Set(data.map(row => row.donor))].map(row => {
return {
groupName: "Donors",
type: "donor",
title: row || "null"
};
});
const receivers = [...new Set(data.map(row => row.receiver))].map(row => {
return {
groupName: "Receivers",
type: "receiver",
title: row || "null"
};
});
const option2 = [...donors, ...receivers];
export const App = props => {
const [myTempVal, setMyTempVal] = React.useState([]);
return (
<Autocomplete
open
multiple
...
您还可以添加getOptionSelected
来覆盖参考检查:
<Autocomplete
open
multiple
disableCloseOnSelect
disablePortal
renderTags={() => null}
noOptionsText="No labels"
getOptionSelected={(option, value) => option.title === value.title}
renderOption={(option, { selected }) => {
return (
<>
<Checkbox
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={selected}
/>
{option.title}
</>
);
}}
options={option2}
// groupBy={option => option.groupName}
getOptionLabel={option => option.title}
renderInput={params => (
<div>
<div>
<SearchIcon />
</div>
<TextField
variant="outlined"
fullWidth
ref={params.InputProps.ref}
inputProps={params.inputProps}
/>
</div>
)}
/>
答案 1 :(得分:0)
这可以帮助: 替换
checked={selected}
收件人
checked={myTempVal.filter(obj=>obj.title===option.title).length!==0}
完整的解决方案
import React from "react";
import "./styles.css";
import TextField from "@material-ui/core/TextField";
import Autocomplete from "@material-ui/lab/Autocomplete";
import CheckBoxOutlineBlankIcon from "@material-ui/icons/CheckBoxOutlineBlank";
import CheckBoxIcon from "@material-ui/icons/CheckBox";
import Checkbox from "@material-ui/core/Checkbox";
import SearchIcon from "@material-ui/icons/Search";
const icon = <CheckBoxOutlineBlankIcon fontSize="small" />;
const checkedIcon = <CheckBoxIcon fontSize="small" />;
const data = [
{ donor: "Trader Joe's", receiver: "Person-to-Person" },
{ donor: "Trader Joe's", receiver: "Homes with Hope" },
{ donor: "Santa Maria", receiver: "Gillespie Center" },
{ donor: "Santa Maria", receiver: null }
];
export const App = props => {
const donors = [...new Set(data.map(row => row.donor))].map(row => {
return {
groupName: "Donors",
type: "donor",
title: row || "null"
};
});
const receivers = [...new Set(data.map(row => row.receiver))].map(row => {
return {
groupName: "Receivers",
type: "receiver",
title: row || "null"
};
});
const option2 = [...donors, ...receivers];
const [myTempVal, setMyTempVal] = React.useState([]);
return (
<Autocomplete
open
multiple
value={myTempVal}
disableCloseOnSelect
disablePortal
renderTags={() => null}
noOptionsText="No labels"
renderOption={(option, { selected }) => {
return (
<>
<Checkbox
onClick={
()=>{
if(myTempVal.filter(obj=>obj.title===option.title).length!==0){
setMyTempVal([...myTempVal.filter(obj=>obj.title!==option.title)],console.log(myTempVal))
}else{
setMyTempVal([...myTempVal.filter(obj=>obj.title!==option.title),option],console.log(myTempVal))
}
}
}
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={myTempVal.filter(obj=>obj.title===option.title).length!==0}
/>
{option.title}
</>
);
}}
options={option2}
// groupBy={option => option.groupName}
getOptionLabel={option => option.title}
renderInput={params => (
<div>
<div>
<SearchIcon />
</div>
<TextField
variant="outlined"
fullWidth
ref={params.InputProps.ref}
inputProps={params.inputProps}
/>
</div>
)}
/>
);
};
export default App;
答案 2 :(得分:0)
回答这个问题为时已晚,但可能会对某人有所帮助。
在代码中,您已在自动完成功能中添加了onChange事件。当您单击复选框时,它将触发2次,一次为复选框,另一次为自动完成。因此,第二次触发使复选框再次处于未选中状态,因此您可以在控制台中获取值,但复选框仍为空。
您可以在renderOption中删除您的复选框,并使用复选框中已选中和未选中的图标。
renderOption={(option, { selected }) => {
return (
<React.Fragment>
{selected ? <CheckedIcon> : <uncheckedIcon>}
<div>
{option.title}
</div>
</React.Fragment>
</>
);
}}