首页 > 解决方案 > 如何在 React 中将继承转化为组合(示例)?

问题描述

我有两种形式:<Login /><Register />. 两者都有usernamepassword而且注册表也有一个name字段。还有一个login按钮和一个register按钮。他们共享的通用代码只是usernameandpassword所以我想重构我的代码以拥有一个组件<UsernamePassord />并在两者中使用它<Login />and <Register />

到目前为止我做了什么(伪代码):

class UsernamePassword extends React {
    constructor() {
        this.state = {username: "", password: ""}
    }

    render() {
        return <div>
            <input username onChange => setState(username: e.value)
            <input password onChange => setState(password: e.value)
        </div>
}

class Login extends UsernamePassword {

     render() {
        return <>
           { super.render() }
           <button onClick => this.state.username && this.state.password && signIn() />
}

class Register extends UsernamePassword {
     constructor() {
           this.state = {
               ...this.state,
               name: ""
            }
     }
     render() {
        return <>
           <input name onChange => setState(name: e.value)
           { super.render() }
           <button onClick => this.state.username && this.state.password && this.state.name && signUp() />
}

我根本不喜欢这段代码。规模化似乎真的很困难。如何使用 composition 更清洁地完成这项工作?

标签: reactjsoopinheritancecomposition

解决方案


有很多方法可以处理这个问题。您可以创建一个接受道具(在本例中为用户名和密码)并处理值操作的组件。它随后会触发某种onChange事件,通知父级更改并且父级可以管理状态。或者,您可以管理组件中的状态,并创建一个事件处理程序道具来提醒父组件的状态。我根据您的代码制作了第二个场景的工作示例(为简单起见,将基于类的组件更改为功能组件):

import React, { useState } from "react";
import "./styles.css";

const UsernamePassword = ({ onChange }) => {
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");

  const handleChange = () => onChange({ username, password });

  return (
    <div>
      <input value={username} onChange={(e) => setUsername(e.target.value)} />
      <input value={password} onChange={(e) => setPassword(e.target.value)} />
      <button onClick={handleChange}>Click me!</button>
    </div>
  );
};

const Login = () => {
  const onChange = (value) => console.log("Login", value);

  return (
    <>
      <h2>Login</h2>
      <UsernamePassword onChange={onChange} />
    </>
  );
};

const Register = () => {
  const onChange = (value) => console.log("Register", value);

  return (
    <>
      <h2>Register</h2>
      <UsernamePassword onChange={onChange} />
    </>
  );
};

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <Register />
      <Login />
    </div>
  );
}

推荐阅读