【问题标题】:Passing React Hook to functional component将 React Hook 传递给功能组件
【发布时间】:2021-04-29 23:56:32
【问题描述】:

我希望创建一个功能组件,该组件接受一个钩子及其 Set 函数作为参数,并使用这些字段(以及其他一些字段)构造一个关联的输入。遇到传递传播运算符的问题(如“Learning React, 2nd edition”中所述)。以下相关sn-ps,不胜感激!

  1. 接受初始值并返回新钩子及其 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}
    />

【问题讨论】:

    标签: reactjs react-hooks react-functional-component


    【解决方案1】:

    问题

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

    返回为{ value, onChange: (e) =&gt; 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>
      );
    };
    

    解决方案

    将value 和onChange 属性传播到底层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
    />
    

    【讨论】:

    • 太棒了!不仅感谢解决方案,还感谢有关如何进一步改进它的指导。
    【解决方案2】:

    您需要进行一些更改。首先传播props.obj 对象,以便引擎盖下的输入元素可以采用value 和onChange 属性。比如

    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)
    

    而不是() =&gt; setValue(initialValue)

    【讨论】:

      猜你喜欢
      • 2017-02-19
      • 1970-01-01
      • 2020-09-04
      • 1970-01-01
      • 2020-08-04
      • 2019-10-08
      • 2019-12-13
      • 2020-09-07
      • 1970-01-01
      相关资源
      最近更新 更多