React 是一个流行的 JavaScript 库,用于构建 Web 应用程序的用户界面。在大型应用程序中使用 React 是一项重要而挑战性的工作。在这种情况下,良好的代码组织和设计模式至关重要。本文介绍了几种在 React 开发中必学的设计模式。
1. Contain-ment 模式
Contain-ment 模式是一种将组件嵌套在容器组件中的方式,以便控制行为和状态的一致性。这种模式在 React 中非常有用,因为它可以让你在子组件中使用父组件的属性和状态。例如,假设你正在构建一个带有子组件的表单,你可以使用 Contain-ment 模式完美地将其实现。
示例代码:
// www.javascriptcn.com code example
class Form extends React.Component {
constructor(props) {
super(props);
this.state = { username: "" };
}
handleSubmit = (event) => {
event.preventDefault();
console.log(`Submitting form with username: ${this.state.username}`);
};
handleUsernameChange = (event) => {
this.setState({ username: event.target.value });
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<UsernameInput
value={this.state.username}
onChange={this.handleUsernameChange}
/>
<button type="submit">Submit</button>
</form>
);
}
}
function UsernameInput(props) {
return (
<label>
Username:
<input
type="text"
value={props.value}
onChange={props.onChange}
/>
</label>
);
}在此示例中,Form 组件是容器组件,它包含了 UsernameInput 组件。Form 组件将 value 和 onChange 属性传递给 UsernameInput 组件,以便在其内部控制 input 元素的状态。
2. Render Callback 模式
Render Callback 模式是一种将函数作为属性传递给组件的方式,使组件可以在渲染时使用这些函数。这种模式在 React 中非常流行,因为它可以使组件更加可重用和可定制。例如,假设你的应用程序中有一个具有一些数据库操作的组件,并且你想要将这些操作与渲染逻辑分离。
示例代码:
// www.javascriptcn.com code example
class Item extends React.Component {
handleDelete = () => {
this.props.onDelete(this.props.id);
};
render() {
return (
<div>
<span>{this.props.text}</span>
<button onClick={this.handleDelete}>Delete</button>
</div>
);
}
}
class ListWithDelete extends React.Component {
handleDelete = (id) => {
this.props.onDelete(id);
};
render() {
return (
<ul>
{this.props.items.map((item) => (
<li key={item.id}>
{item.text}{" "}
{this.props.renderDeleteButton &&
this.props.renderDeleteButton({
id: item.id,
onDelete: this.handleDelete,
})}
</li>
))}
</ul>
);
}
}
function App() {
const items = [
{ id: "1", text: "Item 1" },
{ id: "2", text: "Item 2" },
{ id: "3", text: "Item 3" },
];
return (
<div>
<ListWithDelete
items={items}
onDelete={(id) => console.log(`Deleting item with id: ${id}`)}
renderDeleteButton={({ id, onDelete }) => (
<Item id={id} text="Delete" onDelete={onDelete} />
)}
/>
</div>
);
}在此示例中,ListWithDelete 组件是一个带有删除按钮的列表组件,它接受一个 renderDeleteButton 属性作为函数。renderDeleteButton 函数返回一个组件,该组件将在每个列表项后面渲染。App 组件将 ListWithDelete 组件作为其子组件,并通过 renderDeleteButton 属性将 Item 组件的实例传递给 ListWithDelete 组件。
3. Higher Order 组件模式
Higher Order 组件模式是一种将组件作为参数传递给函数并返回新组件的方式。这种模式在 React 中非常有用,因为它可以帮助你重用代码和逻辑。例如,假设你有一组需要相同功能和逻辑的组件,你可以使用 Higher Order 组件模式来封装这些组件。
示例代码:
// www.javascriptcn.com code example
function withIsHovered(Component) {
return class extends React.Component {
constructor(props) {
super(props);
this.state = { isHovered: false };
}
handleMouseEnter = () => {
this.setState({ isHovered: true });
};
handleMouseLeave = () => {
this.setState({ isHovered: false });
};
render() {
return (
<div
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
>
<Component isHovered={this.state.isHovered} {...this.props} />
</div>
);
}
};
}
function Button(props) {
const backgroundColor = props.isHovered ? "lightblue" : "white";
return (
<button style={{ backgroundColor }} onClick={props.onClick}>
{props.children}
</button>
);
}
const HoverableButton = withIsHovered(Button);
function App() {
return (
<div>
<HoverableButton onClick={() => console.log("Button clicked!")}>
Hover me!
</HoverableButton>
<HoverableButton onClick={() => console.log("Button clicked!")}>
And me!
</HoverableButton>
</div>
);
}在此示例中,withIsHovered 函数是一个 Higher Order 组件,它将组件作为参数传递并返回一个包含 isHovered 状态逻辑的新组件。Button 组件是一个普通的组件,App 组件将 HoverableButton 组件作为其子组件,并通过 withIsHovered 函数来增强 Button 组件。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/67d08d34e46428fe9eda5c1e