如果添加了新元素,则单选按钮onChange事件不会触发



希望你一切顺利,我偶然发现了一个我不理解的问题,在进一步研究我继承的(相当复杂的(代码之前,我想与你核实一下这是否是预期的行为。

{Object.keys(locations).map((keyName) => {
const { name: territoryName, code: territoryCode } = locations[keyName];
return (
<RadioButton
key={`LGRB${territoryName}`}
style={{ margin: '10px 0' }}
onChange={() => console.log('onChange')}
checked={territoryCode === selectedTerritoryCode}
name={territoryName}
label={territoryName}
dark
rightAlign
/>
);
})}

所有操作都很好,正如预期的那样,它呈现了一系列具有可选位置的单选按钮,onChange按预期触发。

如果我现在将一个新元素推送到locations,它会正确地呈现新元素,但是:

  • 用户第一次单击任何单选按钮时,onChange事件不会触发
  • 用户第二次单击任何单选按钮时,onChange事件现在会触发

为什么?

感谢您的帮助

编辑:

这是<RadioButton>组件:

import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { RadioButton as GrommetRadioButton } from 'grommet';
const RadioButtonWrapper = styled.div`
StyledComponentsStyles omitted
`;
const RadioButton = ({ dark, rightAlign, ...props }) => (
<RadioButtonWrapper dark={dark} rightAlign={rightAlign}>
<GrommetRadioButton {...props} />
</RadioButtonWrapper>
);
RadioButton.propTypes = {
dark: PropTypes.bool,
rightAlign: PropTypes.bool,
};
export default RadioButton;

我认为如何处理选中的RadioButton的状态存在问题。为了消除处理此状态的混乱以及呈现单个RadioButton时产生的这些奇怪的副作用,请尝试查看RadioButtonGroup是否正在解决您的问题,控制RadioButton的输入事件和状态管理将更简单。

对于POC,这里有一个使用RadioButtonGroup的示例代码,其中动态添加了RadioButton项,这些项对onChange事件做出预期的反应(双关语(。

import React, { useState } from "react";
import { render } from "react-dom";
import { grommet, Box, Grommet, RadioButtonGroup } from "grommet";
export const App = () => {
const [fruits, setFruits] = useState(["pear", "banana", "mango"]);
const [value, setValue] = useState(fruits[0]);
const [counter, setCounter] = useState(0);
const handleOnChange = (event) => {
console.log(event.target.value);
setValue(event.target.value);
setFruits([...fruits, "apple" + counter]);
setCounter(counter + 1);
};
return (
<Grommet theme={grommet}>
<Box pad="small">
<RadioButtonGroup
name="radio"
options={fruits}
value={value}
onChange={(event) => handleOnChange(event)}
/>
</Box>
</Grommet>
);
};
render(<App />, document.getElementById("root"));

我不确定这是否是你所希望的答案,但如果你计划重构当前行为,请将其视为最佳实践建议。祝你好运

最新更新