React 应用 SOLID 原则 04
定义:依赖倒置原则指出“要依赖于抽象,不要依赖于具体”。换句话说一个组件不应该依赖于另一个组件,而是他们应该依赖于一些共同的抽象。这里“组件”是指应用程序的任何部分,可以是 React 组件,函数,模块或第三方库。
代码演示:
有一个 LoginForm 组件,他在提交表单时将用户凭据发生到某些 API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import api from "~/common/api";
const LoginForm = () => { const [email, setEmail] = useState(""); const [password, setPassword] = useState("");
const handleSubmit = async (evt) => { evt.preventDefault(); await api.login(email, password); };
return ( <form onSubmit={handleSubmit}> <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} /> <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} /> <button type="submit">Log in</button> </form> ); };
|
在这段代码中,LoginForm 组件直接引用了 api 模块,因此他们直接存在紧密耦合。这种依赖关系会导致一个组件的更改会影响其他组件。依赖倒置原则就是提倡打破这种耦合。
如何优化:
首先从 LoginForm 中删除对 api 模块的直接引用,允许通过 props 传入所需回调函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| type Props = { onSubmit: (email: string, password: string) => Promise<void>, };
const LoginForm = ({ onSubmit }: Props) => { const [email, setEmail] = useState(""); const [password, setPassword] = useState("");
const handleSubmit = async (evt) => { evt.preventDefault(); await onSubmit(email, password); };
return ( <form onSubmit={handleSubmit}> <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} /> <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} /> <button type="submit">Log in</button> </form> ); };
|
通过这样修改,LoginFrom 组件不再依赖于 api 模块,向 api 提交凭证的逻辑是通过 onsubmit 毁掉函数抽象出来,现在由父组件负责提供该逻辑的具体实现。
为此创建一个 ConnectedLoginForm 组件来将表单提交逻辑委托给 api 模块
1 2 3 4 5 6 7 8 9
| import api from "~/common/api";
const ConnectedLoginForm = () => { const handleSubmit = async (email, password) => { await api.login(email, password); };
return <LoginForm onSubmit={handleSubmit} />; };
|
ConnectedLoginForm 组件充当 api 和 LoginForm 之间的粘合剂,而他们本身保持完全独立,这样就可以对这两个组件进行单独的修改和维护,而不必担心修改会影响其他组件。
依赖倒置原则就是为了最小化应用程序不同组件之间的耦合。
总结:
应用 SOLID 原则使我们的 React 代码更易于维护和健壮,但需要注意的是,过分遵循这些原则可能会造成破坏并导致代码过度设计。因此我们需要学会识别对组件进一步分解或解耦在什么时候会导致复杂度上升而没有带来任何好处。