Является ли это эффективной реализацией компонента более высокого порядка (HO C) в React? - PullRequest
0 голосов
/ 06 января 2020

Я задал этот вопрос вчера: Реагирует на метод совместного использования компонентов

import React from 'react';

class LoginForm extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            email: '',
            password: '',
        };

        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(e) {
        const target = e.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;

        this.setState({
            [name]: value
        });
    }

Поскольку я многократно использую handleChange(e) во всем приложении, я решил разделить его на компонент более высокого порядка, такой как:

import React from 'react';

const withHandleChange = (WrappedComponent) => {
    return class extends React.Component {
        constructor(props) {
            super(props);

            this.state = {
            };
        }

        handleChange = e => {
            const target = e.target;
            const value = target.type === 'checkbox' ? target.checked : target.value;
            const name = target.name;

            this.setState({
                [name]: value
            });
        }

        render() {
            return (
                <WrappedComponent
                    handleChange={this.handleChange}
                    form={this.state}
                    {...this.props}
                />
            );
        }
    }
};

export default withHandleChange;

Вместо того, чтобы LoginForm поддерживать состояние полей ввода, теперь у меня есть HO C contribli sh, и я передаю это состояние вниз как опора под названием form. Я также передаю метод handleChange как реквизит.

И в исходном компоненте LoginForm я отображаю следующее:

<input type="text" placeholder="Email" name="email" value={this.props.form.email} onChange={this.props.handleChange} />

Я завернул LoginForm следующим образом:

const WrappedLoginForm = withHandleChange(LoginForm);

const LoginBox = props => (
    <div className="login-box">
        <WrappedLoginForm />
    </div>
);

Это допустимая реализация? Мои главные две проблемы: (1) передать состояние в качестве опоры до WrappedComponent в определении withHandleChange и (2) рендеринг WrappedLoginForm, так как я прочитал, что вы не должны использовать HOC внутри метода рендеринга.

Что касается (1), это эффективно? Есть ли лучший способ выполнить sh то, что я делаю?

Что касается (2), я думаю, они имели в виду, что я не должен запускать функцию HO C внутри метода рендеринга, но просто использование обернутого компонента (как я делаю сейчас) должно быть хорошо. Однако я немного растерялся и был бы признателен за подтверждение.

Любые и все предложения будут полезны. Спасибо!

1 Ответ

0 голосов
/ 06 января 2020

Запрещено использовать HOC в жизненном цикле рендеринга, потому что приведенное ниже выражение

const WrappedLoginForm = withHandleChange(LoginForm);

объявляет компонент. И вы знаете, что жизненный цикл рендеринга может выполняться более одного раза, зависит от того, что именно происходит с вашим приложением. Тогда в результате более одного раза будет выполнено объявление обернутого компонента, что может привести к неожиданному поведению. Я думаю, что это root причина, по которой это запрещено.

Чтобы избежать такого рода ошибок, настоятельно рекомендуется объявлять упакованный компонент в том месте, где внутренний компонент экспортируется (или импортируется). Нравится: LoginForm. js

export default withHandleChange(LoginForm)

или

import LoginForm from 'somewhere'

const WrappedLoginForm = withHandleChange(LoginForm);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...