高度可重用的反应组件,无需更改任何代码,仅使用属性

时间:2016-07-12 12:52:03

标签: reactjs

我想创建一个组件,我可以在没有任何代码更改的情况下重用其他项目(仅通过传递不同的属性)。 一个小例子: 我有一个登录表单,其中包含用户名输入和密码输入,例如:

class Login extends Component {

   static propTypes = {
    login: PropTypes.func.isRequired,
    defaultEmailValue: PropTypes.string,
    defaultPasswordValue: PropTypes.string,
  };

  handleSubmit = (event) => {
    if (event) {
      event.preventDefault();
    }

    const username = this.refs.username;
    const password = this.refs.password;
    this.props.login(username.value, password.value);
  };


  render() {
    const {
      defaultEmailValue,
      defaultPasswordValue,
      } = this.props;

    return (
      <form method="post">
        <input defaultValue={defaultEmailValue} ref="username" type="email" />
        <input defaultValue={defaultPasswordValue} ref="password" type="password" />
        <button onClick={this.handleSubmit} type="submit">Submit</button>
      </form>
    );
  }
}

这是登录表单的最小版本,但是当我想扩展render函数以添加像这样的容器组件(添加列标签)时该怎么办:

class Login extends Component {

   /*....*/

  render() {
    const {
      defaultEmailValue,
      defaultPasswordValue,
      } = this.props;

    return (
      <form method="post">
        <div class="row">
           <div class="col-md-6">
              <input defaultValue={defaultEmailValue} ref="username" type="email" />
           </div>
           <div class="col-md-6">
              <input defaultValue={defaultPasswordValue} ref="password" type="password" />
           </div>
        </div>
        <button onClick={this.handleSubmit} type="submit">Submit</button>
      </form>
    );
  }
}

因此我总是要修改渲染功能。是否有可能仅通过属性执行此操作? 我估计在Login组件上使用Wrapper-Component执行此操作,但我总是重写完整的渲染功能。 我想到的下一个可能的解决方案是通过可以呈现的属性传递包装器组件类。但这是一个很好的解决方案,还是这种不好的做法?

不幸的是,我在互联网上找不到本教程的真正解决方案,因此我在这里尝试。在此先感谢: - )

1 个答案:

答案 0 :(得分:0)

  

是否有可能只使用属性来执行此操作?

具有代表性的组件正是出于这种情况。

export default const LoginForm = (/**props**/ {username, email, submitHandler, errors}) => {
  return (
     <form>
       {/* as usual */}
     </form>
  )
}

在ContainerComponent中使用:

...
render() {
  return (
    <div className="loginWrapper">
       <LoginForm ...this.props ...this.state ...whatever username="pete" />
    </div>
  )
}
...