简体   繁体   中英

Function not being passed as prop to child component in React

I want to pass a method from a parent component to a child. The method, however, never appears in the props of the child component. I do not understand what is wrong with this, this is the absolute basic thing to do in React, and it just won't work. Of course, it works fine in about hundred other places in the app codebase. The method in question is getVerificationStatus . It gets invoked in child as a follow up on a promise returned by calling verifyStripeProviderAccount . The child component also has 5 other props passed in by HOCs, and they all work, it's just this one parent prop that is simply not injected for some reason.

The function is undefined, all other props from redux, stripe, etc are present, and the error I am getting is : "TypeError: this.getVerificationStatus is not a function at http://localhost:3000/static/js/main.chunk.js:8837:16 "

The code is below, but I have removed some irrelevant parts for brevity. Parent:

import {getUserVerificationStatus} from "../services/UserService";

class VerifyAccount extends Component {

    state = {
        verificationStatus: VerificationStatus.UNVERIFIED
    };

    componentDidMount() {
        this.getVerificationStatus();
    };

    getVerificationStatus = () => {
        if (this.props.user.paymentProcessorId) {
            getUserVerificationStatus()
                .then(response => this.setState({
                    ...this.state,
                    verificationStatus: response.status || this.state.verificationStatus
                }));
        }
    };

    render() {
        return <Card>
                {this.state.verificationStatus === VerificationStatus.UNVERIFIED && (
                    <VerificationSteps getVerificationStatus={this.getVerificationStatus}/>
                )}
                {this.state.verificationStatus === VerificationStatus.PENDING && (
                    ...
                )}
            </Card>;
    }
}

const mapStateToProps = state => {
    return ...
};

const mapDispatchToProps = (dispatch) => {
    return ...
};

const StripeVerifyAccount = compose(
    withAuthentication,
    withUserType(UserType.PROVIDER),
    injectStripe,
    withStyles(styles, {withTheme: true}),
    injectIntl,
    connect(mapStateToProps, mapDispatchToProps),
)(VerifyAccount);

export default () => {
    return <>
        <Elements>
            <StripeVerifyAccount/>
        </Elements>
    </>;
}

the child:

import {verifyStripeProviderAccount} from "../services/UserService";

class VerificationSteps extends Component {

    state = {...}

    handleSubmit = event => {
        event.preventDefault();

        verifyStripeProviderAccount(body)
            .then(errors => {
                if (errors) {
                    this.props.emitError("verification_documents_error", 5000);
                } else {
                    this.props.getVerificationStatus();
                    this.setState({
                        ...this.state,
                        loading: false,
                        success: true
                    });
                }
            })
            .catch(err => {
                this.setState({
                    ...this.state,
                    loading: false
                });
                this.props.emitError("verification_error")
            });
    };

    render() {
        return <some stuff, not important>
    }

}

const mapStateToProps = state => {
    return ...
};

const mapDispatchToProps = (dispatch) => {
    return ...
};

export default compose(
    withAuthentication,
    withUserType(UserType.PROVIDER),
    injectStripe,
    injectIntl,
    connect(mapStateToProps, mapDispatchToProps),
)(VerificationSteps);

This happens because the call to verifyStripeProviderAccount() is not within a method of your child class, thus this is not properly initialized at that moment. I would even expect you to have a syntax error actually.

Try with:

import {verifyStripeProviderAccount} from "../services/UserService";

class VerificationSteps extends Component {

state = {...}

async componentDidMount(){
    verifyStripeProviderAccount(body)
            .then(errors => {
                if (errors) {
                    ...
                } else {
                    this.props.getVerificationStatus();
                    this.setState({
                        ...
                    });
                }
            })
            .catch(err => {
                this.props.emitError("verification_error")
            });
}

render() {
        return <some stuff, not important>
    }
}

const mapStateToProps = state => {
    return ...
};

const mapDispatchToProps = (dispatch) => {
    return ...
};

export default compose(
    withAuthentication,
    withUserType(UserType.PROVIDER),
    injectStripe,
    injectIntl,
    connect(mapStateToProps, mapDispatchToProps),
)(VerificationSteps);

In a parent component, I have

    setPerson = (person) => {
    this.setState({
        person: person
    })
}

I pass it to a Form Component like so

     <EditLinkForm
         person_id={this.state.person.id}
         link_id={this.state.link_id}
         link_name={this.state.link_name}
         link_url={this.state.link_url}
         setPerson={this.setPerson}
      />

Then this is how the Form (the Child Component) uses it

       axios.post(process.env.REACT_APP_API_URL + '/admin/edit_link/',
        postData,
        AuthenticationService.getAxiosConfig()
        )
           .then(response => {
                this.props.setPerson(response.data.person)
            }
        )

The full source is here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM