среда, 14 июня 2017 г.

TypeScript React Types

import * as React from 'react';
import * as ReactDOM from 'react-dom';

interface IProps {
    myProp?: number;
    myFunc?: (text: string) => void;
}

interface IState {
    myState: number
}

class MyComponent extends React.Component<IProps, IState> {
    // Private
    private timeoutId: number;
    // Prop types
    static defaultProps: IProps = {
        myProp: 0,
        myFunc: () => {alert('По умолчанию.');},
    }
    static propTypes = {
        myProp: React.PropTypes.number,
        myFunc: React.PropTypes.func
    }
    // Public
    // Mounting
    public constructor (props: IProps, context: any) {
        super(props);
        this.state = {
            myState: 456
        };
        this.handleMyFuncClick = this.handleMyFuncClick.bind(this);
        this.handleChangeStateClick = this.handleChangeStateClick.bind(this);
        console.log('1. Компонент создан.');
    }
    public componentWillMount (): void {
        console.log('2. Компонент будет смонтирован.');
        this.timeoutId = setTimeout(() => {this.setState(Object.assign({}, this.state, {myState: this.state.myState + 5}));}, 5000);
    }
    public render (): JSX.Element {
        console.log('3. Компонент отрендерен.');
        return (
            <div>
                <h1>Мой компонент.</h1>
                <p>Моё свойство: {this.props.myProp}</p>
                <button onClick={this.handleMyFuncClick}>Моя функция</button>
                <p>Моё состояние: {this.state.myState}</p>
                <button onClick={this.handleChangeStateClick}>Изменить моё состояние</button>
            </div>
        );
    }
    public componentDidMount  (): void {
        console.log('4. Компонент смонтирован.');
    }
    // Updating
    public componentWillReceiveProps (nextProps: Readonly<IProps>, nextContext: any): void {
        console.log('5. Компонент получил новые свойства.');
    }
    public shouldComponentUpdate (nextProps: Readonly<IProps>, nextState: Readonly<IState>, nextContext: any): boolean {
        console.log('6. Компонент проверяется на необходимость обновления.');
        return true;
    }
    public componentWillUpdate (nextProps: Readonly<IProps>, nextState: Readonly<IState>, nextContext: any): void {
        console.log('7. Компонент будет обновлен.');
    }
    public componentDidUpdate (prevProps: Readonly<IProps>, prevState: Readonly<IState>, prevContext: any): void {
        console.log('8. Компонент выполнил обновление.');
    }
    // Unmounting
    public componentWillUnmount (): void {
        console.log('9. Компонент будет демонтирован.');
        clearTimeout(this.timeoutId);
    }
    // Handlers
    private handleMyFuncClick (event: React.SyntheticEvent): void {
        console.log('Вызвана функция из свойства.');
        this.props.myFunc((event.target as HTMLElement).innerText);
    }
    private handleChangeStateClick (): void {
        console.log('Вызвана функция для обновления состояния компонента.');
        this.setState(Object.assign({}, this.state, {myState: this.state.myState + 1}));
    }
}

interface IRootComponentProps {}

interface IRootComponentState {
    mount: boolean;
}

class RootComponent extends React.Component<IRootComponentProps, IRootComponentState> {
    constructor (props: IRootComponentProps) {
        super(props);
        this.state = {mount: true};
        this.handleUpdateChildClick = this.handleUpdateChildClick.bind(this);
        this.handleUnmountChildClick = this.handleUnmountChildClick.bind(this);
    }
    render (): JSX.Element {
        return (
            <div>
                {
                        this.state.mount
                    ? <MyComponent myProp={123} myFunc={function (text: string): void {alert(text);}} />
                    : null
                }
                <button onClick={this.handleUpdateChildClick}>Обновить дочерний компонент</button>
                <button onClick={this.handleUnmountChildClick}>Удалить дочерний компонент</button>
            </div>
        );
    }
    private handleUpdateChildClick (): void {
        this.setState({mount: true});
    }
    private handleUnmountChildClick (): void {
        this.setState({mount: false});
    }
}

ReactDOM.render(<RootComponent />, document.getElementById('root'));

Комментариев нет:

Отправить комментарий