This article mainly introduces you to the decoupling of advanced components in React. The article introduces the method of component segmentation and decoupling through detailed example code, which is of certain significance to your study or work. Referring to the value of learning, friends who need it can follow the editor to learn together.
Preface
As we all know, the components in React are very flexible and scalable. However, as the business complexity increases and many external tool libraries With the introduction of , components often appear bloated. Next, let’s take a look at some common methods of component segmentation and decoupling that follow the single responsibility principle. Without further ado, let’s take a look at the detailed introduction. :
1. Split render function
When a component renders a lot of content, there is a fast and universal The method is to create a sub-render function to simplify the original huge render
class Panel extends React.Component { renderHeading() { // ... } renderBody() { // ... } render() { return ( <p> {this.renderHeading()} {this.renderBody()} </p> ); } }
In order to simplify the sub-render function again, we can also use the Functional Components writing method, which generates It creates a smaller processing unit and is more conducive to testing
const PanelHeader = (props) => ( // ... ); const PanelBody = (props) => ( // ... ); class Panel extends React.Component { render() { return ( <p> // Nice and explicit about which props are used <PanelHeader title={this.props.title}/> <PanelBody content={this.props.content}/> </p> ); } }
2. Use props to pass elements
If a component has a lot of status or configuration, we can use props to pass elements instead of just data. For example, declare a component so that the parent component only focuses on configuration
class CommentTemplate extends React.Component { static propTypes = { // Declare slots as type node metadata: PropTypes.node, actions: PropTypes.node, }; render() { return ( <p> <CommentHeading> <Avatar user={...}/> // Slot for metadata <span>{this.props.metadata}</span> </CommentHeading> <CommentBody/> <CommentFooter> <Timestamp time={...}/> // Slot for actions <span>{this.props.actions}</span> </CommentFooter> </p> ); } }
Parent component
class Comment extends React.Component { render() { const metadata = this.props.publishTime ? <PublishTime time={this.props.publishTime} /> : <span>Saving...</span>; const actions = []; if (this.props.isSignedIn) { actions.push(<LikeAction />); actions.push(<ReplyAction />); } if (this.props.isAuthor) { actions.push(<DeleteAction />); } return <CommentTemplate metadata={metadata} actions={actions} />; } }
3. Use higher-order components
To achieve clicking on a hyperlink of a component and sending the ID of the component, most of our solutions may be as follows
class Document extends React.Component { componentDidMount() { ReactDOM.findDOMNode(this).addEventListener('click', this.onClick); } componentWillUnmount() { ReactDOM.findDOMNode(this).removeEventListener('click', this.onClick); } onClick = (e) => { if (e.target.tagName === 'A') { // Naive check for <a> elements sendAnalytics('link clicked', { documentId: this.props.documentId // Specific information to be sent }); } }; render() { // ... } }
However, there is a problem that the code cannot be reused and the components are duplicated. Construction difficulties and other problems
We can use higher-order components to solve these problems. As the name suggests, a higher-order component is a function, pass it a component, and it returns a new component
function withLinkAnalytics(mapPropsToData, WrappedComponent) { class LinkAnalyticsWrapper extends React.Component { componentDidMount() { ReactDOM.findDOMNode(this).addEventListener('click', this.onClick); } componentWillUnmount() { ReactDOM.findDOMNode(this).removeEventListener('click', this.onClick); } onClick = (e) => { if (e.target.tagName === 'A') { // Naive check for <a> elements const data = mapPropsToData ? mapPropsToData(this.props) : {}; sendAnalytics('link clicked', data); } }; render() { // Simply render the WrappedComponent with all props return <WrappedComponent {...this.props} />; } } return LinkAnalyticsWrapper; }
The simplified code is as follows
class Document extends React.Component { render() { // ... } } export default withLinkAnalytics((props) => ({ documentId: props.documentId }), Document);
The above is the detailed content of Introduction to learning methods of React. For more information, please follow other related articles on the PHP Chinese website!