【问题标题】:fire an onChange event while setting the initial value在设置初始值时触发 onChange 事件
【发布时间】:2021-02-17 22:08:17
【问题描述】:

我正在尝试构建一个选择字段,当列表中只有一个条目时,它将自动“选择”一个条目。我的问题是,在设置列表中的值时不会触发 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>);
};

【问题讨论】:

  • ` onChange={props.onChange}` - 应该是这样的
  • @UKS 感谢您的建议。但是没有调用 onChange 函数。貌似这个handler只在下拉的onClose方法中调用了
  • onChange 将在我们更改 menuItem 时触发。

标签: reactjs material-ui


【解决方案1】:

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

onChange={props.onChange()}

每次渲染都会调用该函数。

onChange={props.onChange}

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

【讨论】:

  • 感谢您的建议。但是没有调用onChange函数
【解决方案2】:

从您的代码看起来还不错,但是有一件事情可能会导致您的问题。

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>);

我改变了你设置 onchange 函数的方式。您这样做的同时还调用了实际函数。这将在组件呈现时触发函数,而不是在更改此选择的控制值时触发。

【讨论】:

  • 感谢您的建议。但是没有调用onChange函数
  • 好的,如果您可以显示更多代码,那么调试起来会更容易。 Select 组件返回什么?
  • 您的选择需要将 selectedValue 作为值。你可以用你的 menuEntries 数组循环出选项并像上面一样返回它:menuEntries.map(menuEntry =&gt; (&lt;option value={menuEntry}&gt;{menuEntry}&lt;/option&gt;))
【解决方案3】:

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

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

....
} else if (props.addSelectEntry) {
    props.menuEntries.push({"name":t("select"), "value":""}); // This line could be faulty
}
....

我不知道menuEntries 是什么值,但它应该是组件树中更高位置的状态。您还应该传入 setter。可能叫做setMenuEntries。然后调用该设置器而不是改变道具。

setMenuEntries([...menuEntries, {"name":t("select"), "value":""}])

只有在设置状态时才会触发重新渲染。

一般来说,在遵循不变性原则时,更新任何函数的 props 都被认为是一种不好的做法。 Eslint 可以帮助您表示这样的模式。

【讨论】:

    【解决方案4】:

    如果我设置了初始值,我已经通过自己调用他的处理程序解决了我的问题:

    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>);
    };
    

    【讨论】:

      猜你喜欢
      • 2014-12-16
      • 1970-01-01
      • 2013-08-22
      • 2020-10-20
      • 1970-01-01
      • 2017-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多