【问题标题】:Function not being passed as prop to child component in React函数未作为道具传递给 React 中的子组件
【发布时间】:2020-04-22 07:15:12
【问题描述】:

我想将一个方法从父组件传递给子组件。但是,该方法永远不会出现在子组件的 props 中。我不明白这有什么问题,这是在 React 中要做的绝对基本的事情,它就是行不通的。当然,它在应用程序代码库的大约数百个其他地方也能正常工作。有问题的方法是getVerificationStatus。它在子进程中被调用,作为调用verifyStripeProviderAccount 返回的承诺的后续行动。子组件还有 5 个由 HOC 传入的其他道具,它们都可以工作,只是这一个父道具由于某种原因根本没有被注入。

函数未定义,所有其他来自 redux、stripe 等的道具都存在,我得到的错误是:“TypeError: this.getVerificationStatus is not a function 在http://localhost:3000/static/js/main.chunk.js:8837:16"

代码如下,但为简洁起见,我删除了一些不相关的部分。 家长:

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>
    </>;
}

孩子:

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);

【问题讨论】:

  • "这只是一个父 prop,由于某种原因根本没有注入。" 为什么你认为这个方法没有作为 prop 传递?你有错误吗?您还有哪些其他证据来支持这一说法?
  • 更重要的是,当您运行代码时会发生什么?您预计会发生什么不同?
  • @Code-Apprentice 你是什么意思?我只是希望调用该函数,以便它可以完成其工作。我得到的错误很像你在调用未定义函数时得到的任何其他错误 - “TypeError:this.props.getVerificationStatus 不是函数”。此外,在运行时检查 this.props 时,除了这个单一功能之外,它几乎拥有所有应有的道具。
  • 是的,这回答了我的问题。我建议您编辑您的问题以包含确切的错误消息。
  • 有趣的是,您没有得到“getVerificationStatus 未定义”。所以这个道具是作为东西传递的。我建议使用调试器查看this.props.getVerificationStatus 的值。然后你需要弄清楚为什么它被设置为它实际上是什么而不是你认为你正在传递的函数。我会检查你的 mapStateToProps()mapDispatchToProps() 函数。他们有没有同名的东西getVerificationStatus

标签: reactjs


【解决方案1】:

发生这种情况是因为对verifyStripeProviderAccount() 的调用不在您的子类的方法中,因此此时this 未正确初始化。我什至希望您实际上有语法错误。

尝试:

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);

【讨论】:

  • 抱歉,我试图尽可能地整理代码并删除调用它的实际函数。我编辑了子类的代码,请再看一下。它实际上是在箭头函数中调用的,因此已正确初始化。对 this.setState 或 this.props 的所有调用都按预期工作。
【解决方案2】:

在父组件中,我有

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

我像这样将它传递给表单组件

     <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}
      />

那么Form(子组件)就是这样使用它的

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

完整来源是here

【讨论】:

  • 这很好,但我也一样:1. 在父级中定义一个箭头函数 2. 将该函数作为道具传递给子级 3. 在子级的身体中调用,但它仍然没有不工作,即使它应该。它基本上可以在我的代码库中的任何其他地方工作,除了这个。
猜你喜欢
  • 2022-01-24
  • 2021-05-26
  • 2019-07-03
  • 2019-12-31
  • 2018-08-01
  • 2020-03-12
  • 2017-10-31
  • 2017-04-30
相关资源
最近更新 更多