这是一个反应输入组件:
function Input({ value, setValue }) {
return (
<div>
<input value={value} onChange={event => setValue(event.target.value)} />
<button onClick={() => setValue(value.toUpperCase())}>Capitalize</button>
</div>
);
}
它只是一个普通的输入组件,以及一个将输入值大写的按钮。它应由某些父组件控制:
function Parent() {
let [value, setValue] = useState("");
return <Input value={value} setValue={setValue} />;
}
这很好用,但不是惯用。为了用作香草输入组件的“替代品”,它应该使用onChange
道具,而不是setValue
,相关的区别在于onChange
接受一个合成事件作为setValue
接受字符串时的参数。 (我希望大写按钮的存在对于使用此Input
组件的开发人员来说是“不透明的”。)
我试图通过使输入元素在单击按钮时触发更改事件来使其习惯化(请参见下面的代码片段),但这不会导致onChange
的执行。 (我认为这是由于我不了解React的综合事件系统的细节所致。我浏览了有关该主题的大量文章,但找不到我认为可行的想法。)
function AnotherInput({ value, onChange }) {
let input = useRef();
let handleClick = () => {
input.current.value = value.toUpperCase();
var event = new Event("change" /* also tried "input" */, {
bubbles: true
});
input.current.dispatchEvent(event); // onChange doesn't fire!
};
return (
<div>
<input value={value} ref={input} onChange={onChange} />
<button onClick={handleClick}>Capitalize</button>
</div>
);
}
此外,我觉得我不必在这里使用ref
,因为我不想直接修改DOM。我只想更改控制父组件中的值。
答案 0 :(得分:1)
我通过模拟大写按钮上的event Object
使它起作用。
父项:
function Parent() {
let [value, setValue] = useState("");
return <Input value={value} onChange={(e) => setValue(e.target.value)} />;
}
输入组件:
已编辑:我设法为输入组件提出了更优雅的解决方案:
function Input({ value, onChange: inheritedOnChange }) {
return (
<div>
<input value={value} onChange={inheritedOnChange} />
<button value={value.toUpperCase()} onClick={inheritedOnChange}>Capitalize</button>
</div>
);
}
请注意,出于可读性考虑,我将onChange
道具重命名为inheritedOnChange
。在解构过程中保留onChange名称仍然可以正常工作。