将 React Hook 传递给功能组件

Passing React Hook to functional component

我想创建一个功能组件,它将一个挂钩及其 Set 函数作为参数,并使用这些字段(以及其他一些字段)构造一个关联的输入。 运行 涉及传递展开运算符的问题(如“学习 React,第 2 版”中所建议)。以下相关片段,帮助赞赏!

  1. 接受初始值和 returns 新挂钩及其 setValue 函数的通用函数:
    export const useInput = (initialValue) => {
      const [value, setValue] = useState(initialValue);
      return [
        { value, onChange: (e) => setValue(e.target.value) },
        () => setValue(initialValue),
      ];
    };
  1. 要使用的钩子:
    const [firstName, setFirstName] = useInput("");
  1. 功能组件(经过一些清理)
      const MyInputComp = (props) => {
        return (
          <div>
            <input
              className="blah-blah-blah"
              {props.obj}   // *ERROR*
              type="text"
              placeholder={props.placeholder}
              required={props.required}
            />
          </div>
        );
      };
  1. 调用组件的方式如下:
    <MyInputComp
        text="First Name"
        obj={...firstName}  // *ERROR*
        placeholder="Jon"
        required={true}
    />

问题

您没有正确使用输入值和更新程序。

返回为 { value, onChange: (e) => setValue(e.target.value) }

但是你作为obj

单独通过
obj={...firstName}

const MyInputComp = (props) => {
  return (
    <div>
      <input
        className="blah-blah-blah"
        {props.obj}   // *ERROR*
        type="text"
        placeholder={props.placeholder}
        required={props.required}
      />
    </div>
  );
};

解决方案

valueonChange 道具传播到底层 input

const MyInputComp = (props) => {
  return (
    <div>
      <input
        className="blah-blah-blah"
        {...props.obj} // <-- spreads value & onChange props
        type="text"
        placeholder={props.placeholder}
        required={props.required}
      />
    </div>
  );
};

由于 MyInputComp 似乎只是代理了一些道具,您可以将它们全部散布在 中,然后 解构您需要的东西。

const MyInputComp = (props) => {
  return (
    <div>
      <input
        className="blah-blah-blah"
        {...props} // <-- spread all passed props
        type="text"
      />
    </div>
  );
};

使用

const [firstName, setFirstName] = useInput("");

<MyInputComp
    text="First Name"
    {...firstName} // <-- spread to input
    placeholder="Jon" // <-- spread to input
    required={true} // <-- spread to input
/>

您需要做几处更改。首先传播 props.obj 对象,以便引擎盖下的输入元素可以采用 valueonChange 属性。比如

const MyInputComp = (props) => {
  return (
    <div>
      <input
        className="blah-blah-blah"
        {...props.obj}
        type="text"
        placeholder={props.placeholder}
        required={props.required}
      />
    </div>
  );
};

然后像那样渲染 MyInputComp

 <MyInputComp
      text="First Name"
      obj={firstName}
      placeholder="Jon"
      required={true}
      onChange={handleNameChange}
/>

同样在自定义 useInput 挂钩中,更改函数应该像

(value) => setValue(value)

而不是() => setValue(initialValue)