【问题标题】:Override input value in Child component in React在 React 的子组件中覆盖输入值
【发布时间】:2023-02-04 23:38:18
【问题描述】:

我有一个子输入组件和我设置值的父组件。

父组件

const \[dummyText, setDummyText\] = useState('')
return (

<Input
  {...props}
  id="first-name"
  label="First name"
  type="text"
  placeholder="Please enter your first name"
  value={dummyText}
  onChange={(value) => setDummyText(value.target.value)}
/>
)

子输入组件

    import React, { InputHTMLAttributes, forwardRef } from 'react'
    export type Props = {} & InputHTMLAttributes<HTMLInputElement>

    const FormInput: React.FC<Props> = forwardRef<HTMLInputElement, Partial<Props>>(
      ({ ...props }, ref) => <input ref={ref} {...props} />
    )

    FormInput.displayName = 'FormInput'

    export default FormInput

我想在子组件中添加按钮,点击我需要清除该值。

问题是我想在子组件中有明确的功能,我不想为父组件中的每个 <Input 编写额外的代码,无论我在子组件中做什么,我都无法覆盖 props.value。

有没有人有解决这个问题的经验?

【问题讨论】:

  • 你能分享你的Input组件吗?
  • @RubenSmn 我更新了我的代码。发件人

标签: reactjs input parent


【解决方案1】:

如果你想清除输入值,你可以像这样将清除函数作为 prop 传递给子组件:

const Input = ({ onClearInput, ...otherProps }) => {
  return (
    <div style={{ display: 'flex', gap: '.5rem' }}>
      <input {...otherProps} />
      <button onClick={onClearInput}>Clear</button>
    </div>
  );
};

export default function App() {
  const [firstName, setFirstName] = useState('');
  const [secondName, setSecondName] = useState('');

  const onClearInputHandler = (handler) => handler('');

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '.5rem' }}>
      <Input
        id="first-name"
        label="First name"
        type="text"
        placeholder="Please enter your first name"
        value={firstName}
        onChange={(event) => setFirstName(event.target.value)}
        onClearInput={() => onClearInputHandler(setFirstName)}
      />

      <Input
        id="second-name"
        label="Second name"
        type="text"
        placeholder="Please enter your second name"
        value={secondName}
        onChange={(event) => setSecondName(event.target.value)}
        onClearInput={() => onClearInputHandler(setSecondName)}
      />
    </div>
  );
}

因为每个输入都有不同的状态,所以您可以将 useState 中的 set 函数作为参数传递,并在 onClearInputHandler 中运行它以清除值。

【讨论】:

  • 感谢 jcobo1 的努力。问题是,正如我所说,我想在 Child 组件中有一个清晰的函数来覆盖 props.value。我想避免在父级中为每个 <Input 用法编写函数,因为 clear 是我们 <Input 组件的基本“设置”的一部分。
【解决方案2】:

有几个解决方案,我想出了这两个

onClear

我们解构onClear函数,将其添加到清除按钮的onClick中。更新了类型并删除了 Partial,因为它给出了一些错误。

type Props = { onClear: () => void } & InputHTMLAttributes<HTMLInputElement>;

const FormInput: React.FC<Props> = forwardRef<HTMLInputElement, Props>(
  ({ onClear, ...props }, ref) => {
    return (
      <>
        <input ref={ref} {...props} />
        <button onClick={onClear}>clear</button>
      </>
    );
  }
);

现在要使用它,你可以像这样

<Input
  id="first-name"
  onClear={() => setDummyText("")}
  type="text"
  placeholder="Please enter your first name"
  value={dummyText}
  onChange={(event) => setDummyText(event.target.value)}
/>

onValueChange

另一个解决方案可能是将 onChange 重构为 onValueChange,而不是 event 立即返回 value

type Props = {
  onValueChange: (value: string) => void;
} & InputHTMLAttributes<HTMLInputElement>;

const FormInput: React.FC<Props> = forwardRef<HTMLInputElement, Props>(
  ({ onValueChange, ...props }, ref) => {
    return (
      <>
        <input
          ref={ref}
          onChange={(e) => onValueChange(e.target.value)}
          {...props}
        />
        <button onClick={() => onValueChange("")}>clear</button>
      </>
    );
  }
);

这样做的一个问题是,如果提供了 onChange,它将覆盖现有的 onChange。我们可以通过简单地添加它并传递e(事件)来解决这个问题

const FormInput: React.FC<Props> = forwardRef<HTMLInputElement, Props>(
  ({ onValueChange, onChange, ...props }, ref) => {
    return (
      <>
        <input
          ref={ref}
          onChange={(e) => {
            onValueChange(e.target.value);
            onChange(e);
          }}
          {...props}
        />
        <button onClick={() => onValueChange("")}>clear</button>
      </>
    );
  }
);

然后你可以使用

<FormInput
  id="first-name"
  type="text"
  placeholder="Please enter your first name"
  value={dummyText}
  onValueChange={setDummyText}
  // onChange={(e) => console.log(e)}
/>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 2019-01-07
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多