3分钟教你写精炼的 React Components

栏目: IOS · Android · 发布时间: 7年前

内容简介:最近在做一些梳理, 把平时记录的一些笔记和实践整理成完整的短篇技术文章。 这篇主要说一下还是用那个大家都熟悉的 Counter, 点一下就能加1的那种。

最近在做一些梳理, 把平时记录的一些笔记和实践整理成完整的短篇技术文章。 这篇主要说一下 如何精简你的React Components

3分钟教你写精炼的 React Components

看个例子

还是用那个大家都熟悉的 Counter, 点一下就能加1的那种。

看看原始代码:

import React, { Component } from 'react';

class Counter extends Component {
  state = {
    count: 0
  };

  handleClick = () => this.setState(state => ({ count: state.count + 1 }));

  handleReset = () => this.setState({ count: 0 });

  render() {
    const { dark } = this.props;
    const theme = dark ? 'dark' : '';

    return (
      <div className={`clickerLayout ${theme}`}>
        <span className="clickerCount" onClick={this.handleClick}>
          {this.state.count}
        </span>
        <button className="primary" onClick={this.handleReset}>
          Reset
        </button>
      </div>
    );
  }
}

export default Counter;

非常简单的一个组件, 点一下就加1, 点reaset 就重置为0;还能传参换主题。

回头再看这个组件, 发现它虽简单, 做的事情却不少, 甚至有些臃肿。

在 《 Clean Code 》 中, Robert Martint 建议 函数应该专注于一件事:

A function should do one thing, do it well, and do it only.

显然我们的组件没有遵循这条原则, 下面我们就一步步改造成理想的模样:

分离状态管理逻辑

最简单的办法是把状态划分为不同的因子:

import React from 'react';


class Counter extends React.Component {
  state = {
    count: 0
  };
  updateCount = val => this.setState({ count: val });
  render() {
    const stateTools = [this.state.count, this.updateCount];
    return this.props.children(stateTools);
  }
}

const Clicker = props => {
  const { dark, onClick, onReset, count } = props;
  const theme = dark ? 'dark' : '';
  return (
    <div className={`clickerLayout ${theme}`}>
      <span className="clickerCount" onClick={onClick}>
        {count}
      </span>
      <button className="primary" onClick={onReset}>
        Reset
      </button>
    </div>  
  );
}

const App = () => {
  return (
    <Counter>
      {([count, updateCount]) => {
        return (
          <Clicker
            count={count}
            onClick={() => updateCount(count + 1)}
            onReset={() => updateCount(0)}
          />
        )
      }}
    </Counter>
  );
}

export default App;

这样分的一个好处是便于管理,以后不论是 React Hooks, Redux, React.Context, Mobx, Graphql 或者其他什么东西, 都可以。

看到这可能会觉得有点眼熟, 没错, 这是React Render props 的一种形式, 可以参考我的上一篇文章.

分离样式

到现在, 我们的 Clicker component 还是略显臃肿, 继续改。

下一步我们要处理的是样式。

样式是很重要的, 一个组件长成什么样子仅仅是实现要关心的事情, 而且组件本身也不关心你用了什么样的技术。

废话不多少, 我们开始拆:

3分钟教你写精炼的 React Components

拆开之后的这种样子, 很容易创建 styled 的componen, 也方便在其他地方复用。

最终形态

import React from 'react';

const PrimaryButton = props => <button {...props} className="primary" />;

const Clicker = props => <span {...props} className="clickerCount" />;

const ClickerLayout = ({ className="", ...props }) => {
  return <div {...props} className={`clickerLayout ${className}`} />
};

const ClickerLayoutDark = props => (
  <ClickerLayout className="dark" {...props} />
)

class Counter extends React.Component {
  state = {
    count: 0
  };
  updateCount = val => this.setState({ count: val });
  render() {
    const stateTools = [this.state.count, this.updateCount];
    return this.props.children(stateTools);
  }
}

const App = () => {
  return (
    <Counter>
      {([count, updateCount]) => {
        return (
          <ClickerLayoutDark>
            <Clicker onClick={() => updateCount(count + 1)}>{count}</Clicker>
            <PrimaryButton onClick={() => updateCount(0)}>Reset</PrimaryButton>
          </ClickerLayoutDark>
        )
      }}
    </Counter>
  );
}

export default App;

结语

经过一番操作, 代码变成了我们想要的模样,也 干净 了很多。

相比最初的版本多了一些代码,因为我们把一些关键逻辑拆分到了不同的组件中, 干净并不意味着少

如果后面需要加入更多的逻辑, 改造后的版本显然更灵活, 更容易管理。

大概就是这么多, 希望对大家有所启发。

如有纰漏, 欢迎指正, 谢谢。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Creative Curve

The Creative Curve

Allen Gannett / Knopf Doubleday Publishing Group / 2018-6-12

Big data entrepreneur Allen Gannett overturns the mythology around creative genius, and reveals the science and secrets behind achieving breakout commercial success in any field. We have been s......一起来看看 《The Creative Curve》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器