无法在HOC的类函数中访问道具,但能够在渲染器中访问它们

时间:2019-02-15 16:13:50

标签: javascript reactjs react-native react-component

我要实现的目标: 我有很多表单,我想在我的HOC中保留表单验证逻辑,这样我就不必重复验证逻辑,因为大多数表单将具有相同的字段以及一些额外或更少的字段。

我如何实现:

学习创建HOC的方法,遵循此示例HOC example,并尝试创建如下所示的HOC。

import React from 'react';
import {
    spaceCheck,
    specialCharacterCheck,
    numberValidator
} from '../../utility/validators';

const fieldHOC = (WrappedComponent) => {
    class HOC extends React.Component {
            state = {
                error: {
                    name_first: {
                        fieldType: 'name_first',
                        errorType: 0
                    },
                    name_last: {
                        fieldType: 'name_last',
                        errorType: 0
                    },
                    email: {
                        fieldType: 'email',
                        errorType: 0
                    }
                }
            };

    getErrorMessage = (fieldType, errorType) => {
        this.setState({
            error: {
                ...this.state.error,
                [fieldType]: {
                    ...this.state.error[fieldType],
                    errorType
                }
            }
        });
    };

    checkFieldsError = (currentFocus, nextFocus) => {
       //Not able to get props passed by below component in class functions
        console.log('MY PROPS', this.props);
        const field = this.props[currentFocus];
        if (field === '' || spaceCheck(field)) {
            this.getErrorMessage(currentFocus, 1);
        } else if (specialCharacterCheck(field)) {
            this.getErrorMessage(currentFocus, 2);
        } else if (numberValidator(field) || numberValidator(field)) {
            this.getErrorMessage(currentFocus, 3);
        } else {
            this.setState({
                error: {
                    ...this.state.error,
                    [currentFocus]: {
                        ...this.state.error[currentFocus],
                        errorType: 0
                    }
                }
            });
        }
        this[nextFocus].focus();
    }
    render() {
        const { children } = this.props;
         // Here able to access props(name_first, name_last and email) passed from below component 
        // console.log('PROPS', this.props);
        return (
            <WrappedComponent
                {...this.props}
                error={this.state.error}
                checkFieldsError={this.checkFieldsError}
            >
                {children}
            </WrappedComponent>
        );
    }
    }
    return HOC;
};

export default fieldHOC;

我正在使用此HOC的组件

 const FieldValidation = fieldHOC(View);
    class Account extends Component {
        //Some class functions
      render() {
        const { spaceBottom, error } = this.state;
        return (
         <KeyboardAvoidingView
                        style={{ flex: 1 }}
                        keyboardShouldPersistTaps="handled"
                        behavior={Platform.OS === 'ios' ? 'padding' : null}
                    >
                        <KeyboardAwareScrollView
                            keyboardShouldPersistTaps="handled"
                            alwaysBounceVertical={false}
                            contentInset={{ bottom: 0 }}
                        >
                          <FieldValidation
                                name_first={this.state.name_first}
                                name_last={this.state.name_last}
                                email={this.state.email}
                                {...this.props}
                            >
                               <View
                                    style={[
                                        styles.UserContainer,
                                        CommonStyle.shadowStyle
                                    ]}
                                >
                                    <Text style={styles.headingTextStyle}>
                                        Account Details
                                    </Text>
                                    <FormTextInputComponent           
                                         {...testID('first_name')}
                                          errorType={this.props.error.name_first.errorType}
                                          onChangeText={this.handleTextChange('name_first')}
                                          textInputRef={ref => {this.name_first = ref;}}

                                          autoCapitalize="none"
                                          spellCheck={false}
                                          autoCorrect={false}
                                          blurOnSubmit={false}
                                          onSubmitEditing={() => {
                                                    this.props.checkFieldsError('name_first', 'name_last');
                                                }}
                                            />
                                        {this.props.error.name_first.errorType ?
                                                (
                                                    <ErrorMessage textColor="#EA2027" error={error.name_first} />
                                                )
                                                : null}
//Last part 
export default fieldHOC(connect(mapStateToProps)(Account));

在上述组件中,我试图调用以HOC编写的验证函数checkFieldsError。 我面临的问题是,像<FieldValidation这样的name_first中传递的props在HOC的render函数中是可访问的,而相同的props在HOC的类函数中是不可访问的。

我可能最想做的是在React中使用反模式(我猜)。有人可以帮我解决问题和正确的解决方法吗?

编辑:在codeandbox Example

中实现的示例

1 个答案:

答案 0 :(得分:0)

这里是一个codeSandBox example,是我用您要实现的目标创建的,您会注意到,我在HOC内尝试访问其功能中的道具,还请检查控制台以查看控制台日志,请检查代码并遵循相同的示例。您将获得相同的结果。