【问题标题】:Higher Order Component - listening for onChange高阶组件 - 监听 onChange
【发布时间】:2017-09-10 11:27:30
【问题描述】:

我正在开发一个 HOC 来帮助我的 React 应用程序中的表单(用于练习)。

// components/Wrapper.js
import React from 'react';

export default WrappedComponent => class extends React.Component {
  constructor() {
    super();

    this.onSubmit = this.onSubmit.bind(this);
    this.onChange = this.onChange.bind(this);
  }

  onChange(e) {
    console.log(e.target.value);
  }

  onSubmit(e) {
    e.preventDefault();
    console.log("Submitting form...");
  }

  render() {
    return <WrappedComponent {...this.props} onSubmit={this.onSubmit} onChange={this.onChange}/>;
  }
};

然后我使用以下方法从主索引文件中导出:

export Wrapper from './components/Wrapper';

那我可以做:

// LoginPage.js
import { Wrapper } from '../Somewhere'  

...
<form onSubmit={this.props.onSubmit}>
  <label>Email Address</label>
  <input type="text" name="email" onChange={this.props.onChange}/>
  <label>Password</label>
  <input type="password" name="password" onChange={this.props.onChange}/>
  <input type="submit" value="Login"/>
</form>
...

然后我使用:

export default Wrapper(LoginPage);

我正在努力使其尽可能易于使用(因为其他人可能会使用它)。因此,我希望能够删除 input 框中的 onChange 属性并以某种方式构建此功能,以便 HOC 自动检测到 onChanges

如何构建一个可用于自动添加onChange 的输入框的组件?

【问题讨论】:

  • 这是什么语法? export default WrappedComponent =&gt; class extends React.Component {.. 看起来您的 HOC 没有名称,我看不到您在示例中使用它。
  • @jonahe 我省略了这个以使问题更简洁,但现在添加了一些额外的信息。不确定它是否有任何帮助。
  • 你描述它的方式我不确定它是否可以以一种好的方式完成。输入需要以一种或另一种方式获取 onChange 回调。如果您不打算在声明它们时将它们传递(&lt;input type="password" ...etc /&gt;),那么您需要在稍后阶段以某种方式获取对所有输入的引用,可能在您的 HOC 中(因为这是知道如何处理 onChage)。这对我来说听起来很乱。但是,是的,也许我误解了什么。您是否有一个您使用过的现有库的示例,该库的 API 与您想要实现的目标相似?
  • 谢谢。我猜 redux-form 做了类似的事情。如果您创建一个表单并添加Field 组件,那么会自动检测到onChange。我一直在研究源代码一段时间,但不确定是哪一点解决了这个问题。
  • 好吧,是的,redux-form 有一个非常“神奇”的 API,确实如此。快速浏览一下some of the source code,它似乎依赖于这样一个事实,即父级(连接的基础组件)和子级(如Field)都可以访问相同的上下文。示例:if (!context._reduxForm) { throw new Error ..。所以我认为你必须让输入组件也是自定义的。但是,是的,我不会假装完全理解它,甚至无法复制该功能。

标签: reactjs


【解决方案1】:

你需要在你的 react 组件中包装 html 元素输入,并设置 defaultProps: onChange: () => {},并定义其他 props,如输入类型等...

然后将此输入标记为组件:

<form onSubmit={this.props.onSubmit}>
  <CustomInput type="text" label="Login" .../>
</form>

【讨论】:

  • 这不是我要问的!我知道如何从包装器中传递道具,因为我已经在问题中证明了这一点。我想知道如何“烘焙” onChange 功能,以便包装器检测文本框中的值何时发生变化(而不将 onChange 添加到输入本身)。
【解决方案2】:

获取输入值的另一种方法是:

  handleSubmit = e => {
    e.preventDefault();

    const name = ReactDOM.findDOMNode(this._nameInput).value;
    const email = ReactDOM.findDOMNode(this._emailInput).value;
    const password = ReactDOM.findDOMNode(this._passwordInput).value;


    // submit the data...
  };

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <input
          ref={nameInput => this._nameInput}
          type="text"
          placeholder="Name"
        />
        <input
          ref={emailInput => this._emailInput}
          type="text"
          placeholder="Email"
        />
        <input
          ref={passwordInput => this._passwordInput}
          type="password"
          placeholder="Password"
        />

        <button type="submit">Submit</button>
      </form>
    );
  }

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 2015-07-05
    • 2018-12-12
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    相关资源
    最近更新 更多