Reactjs 在设置初始值时触发onChange事件

Reactjs 在设置初始值时触发onChange事件,reactjs,material-ui,Reactjs,Material Ui,我试图建立一个选择字段,当列表中只有一个条目时,它会自动“选择”一个条目。我的问题是,在列表中设置值时,不会触发onChange事件。是否有可能通过编程方式发送这些活动 这是到目前为止我的代码 export const SelectField = function(props) { const classes = useStyles(); const {t} = useTranslation(); const [selectedValue, setSelectedVal

我试图建立一个选择字段,当列表中只有一个条目时,它会自动“选择”一个条目。我的问题是,在列表中设置值时,不会触发onChange事件。是否有可能通过编程方式发送这些活动

这是到目前为止我的代码

export const SelectField = function(props) {
    const classes = useStyles();
    const {t} = useTranslation();

    const [selectedValue, setSelectedValue] = React.useState(undefined);

    if (selectedValue === undefined && props.menuEntries.length === 1) {
        setSelectedValue(props.menuEntries[0]);
        //need to fire an event in this case
    } else if (props.addSelectEntry) {
        props.menuEntries.push({"name":t("select"), "value":""});
    }

    return  (
        <Select
            value={selectedValue}
            onChange={props.onChange()}
            name={props.name}
            displayEmpty
            className={classes.selectEmpty}
        >
            {props.menuEntries.map(entry => (
                <MenuItem key={entry.name} value={entry.value}>
                    {entry.name}
                </MenuItem>
            ))}

        </Select>);
};
export const SelectField=函数(道具){
const classes=useStyles();
const{t}=useTranslation();
常量[selectedValue,setSelectedValue]=React.useState(未定义);
if(selectedValue==undefined&&props.menuenties.length==1){
设置选定值(道具菜单项[0]);
//在这种情况下需要触发事件
}else if(props.addSelectEntry){
push({“name”:t(“select”),“value”:“});
}
返回(
{props.menuEntries.map(条目=>(
{entry.name}
))}
);
};

将函数作为道具传递和调用函数有一个重要区别

onChange={props.onChange()}
将在每次渲染时调用该函数

onChange={props.onChange}

将传递该函数以供组件调用。

从代码的外观来看,似乎没有问题,但是有一件事可能会导致您的问题

return  (
        <Select
            value={selectedValue}
            onChange={props.onChange} <---
            name={props.name}
            displayEmpty
            className={classes.selectEmpty}
        >
            {props.menuEntries.map(entry => (
                <MenuItem key={entry.name} value={entry.value}>
                    {entry.name}
                </MenuItem>
            ))}

        </Select>);
返回(
(
{entry.name}
))}
);

我更改了设置onchange函数的方式。您这样做的同时也调用了实际函数。这将使函数在组件渲染时启动,而不是在更改此选择的控制值时启动。

其中一个是提到的
onChange()
onChange
,但这还不是全部

问题似乎与所提供组件之外的代码有关。问题的一个指标如下:

....
} else if (props.addSelectEntry) {
    props.menuEntries.push({"name":t("select"), "value":""}); // This line could be faulty
}
....
我不知道
menuEntries
是什么类型的值,但它应该是组件树中较高位置的状态。你也应该通过二传。可能被称为
setMenuEntries
。然后叫那个二传手进来,而不是改变道具

setMenuEntries([...menuEntries, {"name":t("select"), "value":""}])
只有在设置状态时,才会触发重新加载程序


一般来说,当遵循不变性原则时,更新任何函数的道具都被认为是不好的做法。Eslint可以帮助您标记这样的模式。

如果我设置初始值,我可以通过自己调用处理程序来解决问题:

export const SelectField = function(props) {
    const classes = useStyles();
    const { t } = useTranslation();

    const [selectedValue, setSelectedValue] = React.useState(props.value);

    // on startup load test cases
    React.useEffect(() => {
        if (selectedValue === props.value && props.menuEntries.length === 1) {
            setSelectedValue(props.menuEntries[0].value);
            props.onChange(props.menuEntries[0].value);
        }
    }, [selectedValue]);


    const updateValue = function(e) {
        props.onChange(e.target.value);
        setSelectedValue(e.target.value);
    };

    return (
        <Select
            value={selectedValue}
            onChange={updateValue}
            name={props.name}
            displayEmpty
            className={classes.selectEmpty}
        >
        {
            (props.menuEntries.length !== 1 && props.addSelectEntry) && (
                <MenuItem key={t("select")} value={t("select")}>
                    {t("select")}
                </MenuItem>
            )
        }
            {props.menuEntries.map(entry => (
                <MenuItem key={entry.name} value={entry.value}>
                    {entry.name}
                </MenuItem>
            ))}

        </Select>);
};
export const SelectField=函数(道具){
const classes=useStyles();
const{t}=useTranslation();
const[selectedValue,setSelectedValue]=React.useState(props.value);
//启动负载测试用例
React.useffect(()=>{
if(selectedValue==props.value&&props.menuEntries.length==1){
setSelectedValue(props.menuEntries[0].value);
props.onChange(props.menentries[0].value);
}
},[selectedValue]);
const updateValue=函数(e){
道具变化(如目标值);
设置选定值(如目标值);
};
返回(
{
(props.menuEntries.length!==1&&props.addSelectEntry)&&(
{t(“选择”)}
)
}
{props.menuEntries.map(条目=>(
{entry.name}
))}
);
};

`onChange={props.onChange}`-应该是this@UKS谢谢你的建议。但不会调用onChange函数。看起来只有在下拉列表的onClose方法中调用此处理程序,当我们更改菜单项时,
onChange
将触发该下拉列表。谢谢您的建议。但是onChange函数不是calledOk,如果您可以显示更多的代码,那么调试就更容易了。Select组件返回什么?您的Select需要将selectedValue作为一个值。您可以使用menuEntries数组循环出选项,并像上面那样返回它:
menuEntries.map(menuEntry=>({menuEntry}))
谢谢您的建议。但不调用onChange函数