[译]React 组件解耦之道
分割 render 函数当一个组件渲染的内容较多时,有一个快速并且通用的方法是创建 class Panel extends React.Component { renderHeading() { // ... } renderBody() { // ... } render() { return ( <div> {this.renderHeading()} {this.renderBody()} </div> ); } } 为了再次简化 const PanelHeader = (props) => ( // ... ); const PanelBody = (props) => ( // ... ); class Panel extends React.Component { render() { return ( <div> // Nice and explicit about which props are used <PanelHeader title={this.props.title}/> <PanelBody content={this.props.content}/> </div> ); } } 用 props 传递元素如果一个组件的状态或配置较多,我们可以运用 class CommentTemplate extends React.Component { static propTypes = { // Declare slots as type node metadata: PropTypes.node,actions: PropTypes.node,}; render() { return ( <div> <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> </div> ); } } 父组件 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} />; } } 使用高阶组件实现点击某组件的超链接,发送该组件的 ID,我们大多的解决方法可能如下 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() { // ... } } 然而它却存在 我们可以使用 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; } 简化代码如下 class Document extends React.Component { render() { // ... } } export default withLinkAnalytics((props) => ({ documentId: props.documentId }),Document); 总结以上 3 个 React 组件的
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |