Image Source : https://bugfender.com
React是一个强大的JavaScript库,用于构建用户界面。其基于组件的体系结构和构建可重用组件的能力使其成为许多企业级应用程序的首选。然而,随着应用程序的规模和复杂性的增长,维护和扩展变得更加困难。这就是设计模式发挥作用的地方。在这篇博客文章中,我们将探讨一些最常用的React企业设计模式,以及TypeScript中的代码示例。
容器和呈现组件模式
React中使用最广泛的模式之一是容器和表示组件模式。这种模式将表示逻辑与业务逻辑分离,使代码更加模块化,更易于测试。容器组件负责从服务器获取数据,并将其作为prop传递给表示组件。表示组件负责呈现UI。
// Container Component
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchUsers } from './userActions';
import { RootState } from './rootReducer';
import UserList from './UserList';
const UserListContainer: React.FC = () => {
const dispatch = useDispatch();
const { loading, users } = useSelector((state: RootState) => state.users);
useEffect(() => {
dispatch(fetchUsers());
}, [dispatch]);
return <UserList loading={loading} users={users} />;
};
export default UserListContainer;
// Presentational Component
import React from 'react';
import { User } from './userTypes';
interface Props {
loading: boolean;
users: User[];
}
const UserList: React.FC<Props> = ({ loading, users }) => {
if (loading) return <div>Loading...</div>;
if (!users) return null;
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};
export default UserList;
渲染 Props 图案
"渲染prop "模式是一种使用值为函数的prop在组件之间共享代码的技术。当组件具有相似的功能但具有不同的渲染要求时,此模式非常有用。
import React from 'react';
interface Props {
render: (count: number, increment: () => void) => JSX.Element;
}
const Counter: React.FC<Props> = ({ render }) => {
const [count, setCount] = React.useState(0);
const increment = () => {
setCount(count + 1);
};
return render(count, increment);
};
export default Counter;
// Usage
import React from 'react';
import Counter from './Counter';
const App: React.FC = () => {
return (
<div>
<h1>Render Props Pattern</h1>
<Counter
render={(count, increment) => (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
)}
/>
</div>
);
};
export default App;
高阶组件模式。
高阶组件(HOC)模式是React中的一种设计模式,它通过提供一种增强或修改组件功能的方法来实现组件的可重用性和代码共享。
简单地说,HOC是一个函数,它接受一个组件作为参数,并返回一个具有附加功能的新组件。然后,可以像React中的任何其他组件一样渲染新组件。原始组件由HOC包裹,HOC为包裹的组件提供额外的行为或prop。
HOC可用于广泛的任务,如提供上下文、处理错误、获取数据或强制身份验证。它们可以帮助减少代码重复,提高代码可维护性,并促进代码重用。
import React from 'react';
// Define a higher-order component
const withName = (WrappedComponent) => {
return class extends React.Component {
state = {
name: 'John Doe'
}
render() {
return (
<WrappedComponent name={this.state.name} {...this.props} />
)
}
}
}
// Define a regular component
const MyComponent = (props) => {
return (
<div>
<p>Hello, my name is {props.name}.</p>
<p>I am a {props.role}.</p>
</div>
)
}
// Wrap MyComponent with the withName HOC
const MyComponentWithName = withName(MyComponent);
// Render MyComponentWithName
const App = () => {
return (
<div>
<MyComponentWithName role="developer" />
</div>
)
}
export default App;
禁用prop模式
禁用prop模式是React中使用的一种设计模式,它通过提供一种方法来禁用按钮、链接和表单字段等交互元素(当它们不可用或不适用时),从而能够创建可访问的用户界面。
该模式包括向组件中的交互式元素添加一个禁用的prop,当设置为true时,将禁用该元素并阻止其接收用户输入。这对于由于特定条件(例如表单不完整或用户权限不足)导致交互式元素不适用的情况尤其有用。
import React from 'react';
const App = () => {
return (
<div>
<SomeComponent disabled />
</div>
);
};
const SomeComponent = ({ disabled = false }) => {
return (
!disabled && (
<div>
<h2>Disable SomeComponent to see magic happen!</h2>
</div>
)
);
};
受控和非受控组件模式
受控组件是一个表单元素,其值由React控制。换句话说,组件的值总是通过props显式设置,并通过回调进行更新。这意味着组件的状态始终与输入数据同步,允许React控制组件的行为,并允许开发人员轻松处理用户输入。
import React, { useState } from 'react';
function ControlledInput() {
const [value, setValue] = useState('');
const handleChange = (event) => {
setValue(event.target.value);
};
return (
<input type="text" value={value} onChange={handleChange} />
);
}
不受控制的零部件是由浏览器管理其值的形状元素。换句话说,组件的值由用户设置,React不控制其行为。这会使处理复杂表单中的用户输入变得更加困难,但在简单表单中使用也会更快、更容易。
import React, { useRef } from 'react';
function UncontrolledInput() {
const inputRef = useRef(null);
const handleSubmit = (event) => {
event.preventDefault();
console.log(inputRef.current.value);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={inputRef} />
<button type="submit">Submit</button>
</form>
);
}
复合部件模式
复合组件模式是React中用于管理由多个子组件组成的组件的设计模式。这种模式包括将父组件的关注点分离为较小的组件,然后使用prop、上下文和其他技术的组合来管理这些较小组件之间的关系。
复合组件模式背后的理念是为开发人员提供一种方法,以创建由较小构建块组成的可重复使用、灵活和易于使用的组件。这使开发人员能够创建复杂的UI组件,这些组件可以很容易地进行自定义和扩展,同时仍然保持清晰易懂的代码结构**。**
import React, { createContext, useState } from 'react';
const ToggleContext = createContext();
function Toggle({ children }) {
const [on, setOn] = useState(false);
const toggle = () => setOn(!on);
return (
<ToggleContext.Provider value={{ on, toggle }}>
{children}
</ToggleContext.Provider>
);
}
function ToggleOn({ children }) {
const { on } = useContext(ToggleContext);
return on ? children : null;
}
function ToggleOff({ children }) {
const { on } = useContext(ToggleContext);
return on ? null : children;
}
function ToggleButton(props) {
const { on, toggle } = useContext(ToggleContext);
return <button onClick={toggle} {...props} />;
}
function App() {
return (
<Toggle>
<ToggleOn>The button is on</ToggleOn>
<ToggleOff>The button is off</ToggleOff>
<ToggleButton>Toggle</ToggleButton>
</Toggle>
);
}
prop 集合模式
prop 集合模式是React中用于将prop 集合传递给组件的设计模式。它包括将多个相关prop 组合成一个对象,然后将其作为一个prop传递给组件。
当我们想将大量相关的prop 传递给组件时,这种模式特别有用,因为它可以减少代码中的混乱,并使prop的管理变得更容易。
import React from 'react';
function Button(props) {
const { label, color, size, ...rest } = props;
return (
<button style={{ color, fontSize: size }} {...rest}>
{label}
</button>
);
}
function App() {
const buttonProps = {
label: "Click Me",
color: "red",
size: "20px",
onClick: () => console.log("Button clicked!")
};
return <Button {...buttonProps} />;
}
函数作为子模式
Function as Child模式是React中使用的一种设计模式,它涉及将函数作为子级传递给组件,然后在组件内部调用该组件来呈现实际内容。
import React from 'react';
function Toggle(props) {
const [on, setOn] = useState(false);
const handleToggle = () => {
setOn(!on);
};
return props.children({
on: on,
toggle: handleToggle
});
}
function App() {
return (
<Toggle>
{({ on, toggle }) => (
<div>
{on ? "The button is on" : "The button is off"}
<button onClick={toggle}>Toggle</button>
</div>
)}
</Toggle>
);
}
受控输入模式
受控输入模式是React中用于管理输入字段的模式。它包括将输入字段的当前值存储在组件状态中,并在输入值更改时使用事件处理程序更新状态。
import React, { useState } from "react";
function ControlledInput() {
const [inputValue, setInputValue] = useState("");
const handleInputChange = (event) => {
setInputValue(event.target.value);
};
return (
<div>
<input type="text" value={inputValue} onChange={handleInputChange} />
<p>The input value is: {inputValue}</p>
</div>
);
}
不可变模式
不可变模式通常用于管理组件的状态。我们不直接修改状态,而是使用更新的值创建一个新的状态对象,然后将其传递给组件进行渲染。
Immutable.js库可用于创建不可变的数据结构,这些数据结构可用于React状态管理。以下是如何在React组件中使用不可变模式的示例:
import React, { Component } from 'react';
import { Map } from 'immutable';
class MyComponent extends Component {
state = {
data: Map({
name: 'John',
age: 30,
email: 'john@example.com'
})
};
handleNameChange = (event) => {
const name = event.target.value;
const newData = this.state.data.set('name', name);
this.setState({ data: newData });
};
render() {
const { data } = this.state;
return (
<div>
<label>Name:</label>
<input type="text" value={data.get('name')} onChange={this.handleNameChange} />
<label>Age:</label>
<span>{data.get('age')}</span>
<label>Email:</label>
<span>{data.get('email')}</span>
</div>
);
}
}
在这篇博客文章中,我们讨论了一些最常用的React企业设计模式,包括高阶组件、渲染prop、容器表示组件模式、复合组件、受控组件等等。通过在React项目中应用这些设计模式和最佳实践,您可以提高代码质量,增加团队协作,并使您的应用程序更具可扩展性、灵活性和可维护性。然而,重要的是要记住,这些模式不是一刀切的解决方案,可能需要根据项目的具体要求进行调整。
总的来说,React企业设计模式是一套有价值的工具和技术,可以帮助您构建更好的React应用程序,提高开发生产力和效率,并提供满足用户和利益相关者需求的高质量软件。
编码快乐!
文章链接