Javascript 如何使此react输入组件成为习惯用法?

Javascript 如何使此react输入组件成为习惯用法?,javascript,reactjs,dom-events,react-hooks,Javascript,Reactjs,Dom Events,React Hooks,下面是一个react输入组件: 函数输入{value,setValue}{ 回来 setValueevent.target.value}/> setValuevalue.toUpperCase}>大写 ; } 它只是一个普通的输入组件和一个大写输入值的按钮。这意味着由某个父组件控制: 函数父级{ let[value,setValue]=useState; 回来 } 这很好,但不是惯用语。为了可用作普通输入组件的插入式替换,它应该采用onChange属性,而不是setValue,相关的区别在于on

下面是一个react输入组件:

函数输入{value,setValue}{ 回来 setValueevent.target.value}/> setValuevalue.toUpperCase}>大写 ; } 它只是一个普通的输入组件和一个大写输入值的按钮。这意味着由某个父组件控制:

函数父级{ let[value,setValue]=useState; 回来 } 这很好,但不是惯用语。为了可用作普通输入组件的插入式替换,它应该采用onChange属性,而不是setValue,相关的区别在于onChange采用合成事件作为参数,而setValue采用字符串。我希望大写按钮对使用此输入组件的开发人员来说是不透明的

我试图通过让输入元素在单击按钮时触发一个更改事件来习惯化下面的see代码段,但这不会导致onChange执行。我想这是因为react的合成事件系统的细节我不了解。我浏览了一大堆关于这个话题的帖子,但是没有找到我认为有用的想法

函数的另一个输入{value,onChange}{ 让输入=useRef; 让handleClick==>{ input.current.value=value.toUpperCase; var event=new Eventchange/*也尝试了输入*/{ 泡泡:真的 }; input.current.dispatchEventevent;//onChange不会触发! }; 回来 资本化 ; } 另外,我觉得我不应该在这里使用ref,因为我不想直接修改DOM;我只想更改控制父组件中的值


我通过模拟大写按钮上的事件对象使其工作

父组件:

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>
    );
}
输入组件:

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>
    );
}
编辑:我设法为输入组件想出了一个更优雅的解决方案:

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名称仍然有效

你的第二个解决方案特别聪明!我不知道按钮标签有值属性。传递给onChange的事件的目标将改变输入或按钮,但这似乎相当合理,准确地反映了事件的来源…此外,如果第二个示例中的onChange定义不在@Japsz的代码段中,则需要读取event.currentTarget.value,而不只是读取event.target.value。这花了我20分钟。