【问题标题】:Unable to access props in HOC's class function but able to access them in render无法访问 HOC 的类函数中的道具,但能够在渲染中访问它们
【发布时间】:2019-07-09 19:43:11
【问题描述】:

我想要达到的目标: 我有很多表单,我想在我的 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。 我面临的问题是在&lt;FieldValidation 中传递的道具(如name_first)可以在 HOC 的渲染函数中访问,但在 HOC 的类函数中无法访问相同的道具。

很可能我尝试做的是 React 中的反模式(我猜)。有人可以帮我找出问题和正确的方法吗?

编辑:在代码框Example中实现的示例

【问题讨论】:

  • 为什么你在 View 中使用fieldHOC
  • @RachidRhafour 我试图传递名为 Account 的组件,但出现错误:元素类型无效,需要字符串或类函数但未定义。
  • 你得到什么样的错误?
  • 现在您使用 HOC 两次,其中一次使用没有您在 HOC 中使用的任何道具的组件,以及可能具有这些道具的 Account。
  • @RachidRhafour 那么我应该如何使用它呢?

标签: javascript reactjs react-native react-component


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2018-12-21
    • 2020-02-05
    • 2016-08-31
    • 1970-01-01
    • 2016-08-03
    • 2018-04-24
    • 2021-04-12
    • 2021-06-29
    • 2020-01-31
    相关资源
    最近更新 更多