[关闭]
@bornkiller 2017-08-13T12:00:17.000000Z 字数 1947 阅读 1929

React 组件设计与思考

React


前言

React 组件灵活性极强,理清组件边界,可以更好地运用,最终达到熟能生巧的境界。

原生组件

笔者生造词:独立声明,关联皆内部可见的组件。粗略分为 smart component, dump component两种。

插槽组件

笔者生造词:渲染过程包含外部组件插槽的组件。最简单的插槽模式,暨prop.children方式使用,示例来自官方文档:

  1. function FancyBorder(props) {
  2. return (
  3. <div className={'FancyBorder FancyBorder-' + props.color}>
  4. {props.children}
  5. </div>
  6. );
  7. }
  1. function WelcomeDialog() {
  2. return (
  3. <FancyBorder color="blue">
  4. <h1 className="Dialog-title">
  5. Welcome
  6. </h1>
  7. <p className="Dialog-message">
  8. Thank you for visiting our spacecraft!
  9. </p>
  10. </FancyBorder>
  11. );
  12. }

此处单一插槽,也可以实现多插槽模式,示例来自官方文档:

  1. function SplitPane(props) {
  2. return (
  3. <div className="SplitPane">
  4. <div className="SplitPane-left">
  5. {props.left}
  6. </div>
  7. <div className="SplitPane-right">
  8. {props.right}
  9. </div>
  10. </div>
  11. );
  12. }
  1. function App() {
  2. return (
  3. <SplitPane
  4. left={<Contacts />}
  5. right={<Chat />}
  6. />
  7. );
  8. }

定制组件

笔者生造词:固定通用组件部分传参的组件。

  1. function Dialog(props) {
  2. return (
  3. <FancyBorder color="blue">
  4. <h1 className="Dialog-title">
  5. {props.title}
  6. </h1>
  7. <p className="Dialog-message">
  8. {props.message}
  9. </p>
  10. {props.children}
  11. </FancyBorder>
  12. );
  13. }
  1. class SignUpDialog extends React.Component {
  2. constructor(props) {
  3. super(props);
  4. this.state = {login: ''};
  5. }
  6. handleChange = (e) => {
  7. this.setState({login: e.target.value});
  8. };
  9. handleSignUp = () => {
  10. alert(`Welcome aboard, ${this.state.login}!`);
  11. };
  12. render() {
  13. return (
  14. <Dialog
  15. title="Mars Exploration Program"
  16. message="How should we refer to you?"
  17. >
  18. <input value={this.state.login} onChange={this.handleChange} />
  19. <button onClick={this.handleSignUp}>
  20. Sign Me Up!
  21. </button>
  22. </Dialog>
  23. );
  24. }
  25. }

高阶组件

笔者定义:接受组件参数,返回新组件的函数。

  1. function withLinkAnalytics(RawComponent) {
  2. class LinkAnalyticsWrapper extends React.Component {
  3. componentDidMount() {
  4. ReactDOM.findDOMNode(this).addEventListener('click', this.handleLinkClick);
  5. }
  6. componentWillUnmount() {
  7. ReactDOM.findDOMNode(this).removeEventListener('click', this.handleLinkClick);
  8. }
  9. handleLinkClick = (e) => {
  10. // Naive check for <a> elements
  11. if (e.target.tagName === 'A') {
  12. // Feedback
  13. }
  14. };
  15. render() {
  16. // Never forget passing props
  17. return <RawComponent {...this.props} />;
  18. }
  19. }
  20. }

延伸思考

关于 高阶组件插槽组件,笔者实践中并不能很好的区分两者。个人判断标准为,UI 的协同使用 插槽组件,业务逻辑的协同使用 高阶组件

Contact

Email: hjj491229492@hotmail.com

qrcode_for_gh_d8efb59259e2_344.jpg-8.7kB

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注