React TS 组件 Demo

无状态组件

例子:点击查看大图

import React, { MouseEvent, SFC } from 'react'

type Props = {
  onClick(e: MouseEvent<HTMLElement>): void
  src: string,
  show: boolean,
}

const BigImage: SFC<Props> = ({ onClick, show, src }) => {
  return show ? <div className="big-img-wrap" onClick={onClick}>
      <div className="big-img-content">
        <img src={src} className="big-img"} alt="" />
      </div>
  </div> : null;
}

export default IMBigImage;

参数完全由父容器提供,样式如下

.big-img-wrap {
  position: absolute;
  overflow: hidden;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, .65);
  z-index: 10;
}
.big-img-content {
  position: absolute;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  top: 10%;
  left: 10%;
  bottom: 10%;
  right: 10%;
  background: #FFF;
  border-radius: 8px;
  overflow: hidden;
}
.big-img {
  max-width: 100%;
  max-height: 100%;
  vertical-align: top;
}

有状态组件

例子:按钮点击计数

import React, { Component } from 'react';

import { Button } from 'antd';

type IProps = Readonly<{
  className?: string;
  style?: React.CSSProperties;
  value?: string;
  onChange?: Function;
}>;

const initialState = { clickCount: 0 };
type IState = Readonly<typeof initialState>;

class ButtonCounter extends Component<IProps, IState> {
  readonly state: IState = initialState;
  
  componentWillReceiveProps(nextProps: any) {
    const { value } = nextProps;
    if (value) {
      this.setState({
        clickCount: value
      })
    }
  }

  render() {
    const { clickCount } = this.state;
    const { className, style } = this.props;
    return (
      <div className={`${className}`} style={`${style}`}>
        <Button onClick={this.handleIncrement}>Increment</Button>
        <Button onClick={this.handleDecrement}>Decrement</Button>
        You've clicked me {clickCount} times!
      </div>
    );
  }

  private handleIncrement = () => {
    const { onChange } = this.props;
    const { clickCount } = this.state;
    this.setState({
      clickCount: clickCount + 1,
    });  
    onChange && onChange(clickCount + 1);
  };
  private handleDecrement = () => {
    const { onChange } = this.props;
    const { clickCount } = this.state;
    this.setState({
      clickCount: clickCount - 1,
    });  
    onChange && onChange(clickCount - 1);
  }
}

支持从父容器传递样式更改。

使用 componentWillReceiveProps 是为了能把父组件的 value 同步给子组件。完整的组件数据传递就该是 父传子,触发子的 componentWillReceiveProps 来同步数据,然后操作子更改状态并把动作传给父。

使用了 Readonly 将 IProps 和 IState 设为只读,是为了防止其他函数里改动它们。

参考

TypeScript 2.8下的终极React组件模式