接收错误:this.props.toggle()不是反应中的函数

时间:2018-03-17 06:10:30

标签: reactjs react-component

我正在尝试从子组件调用父组件函数,但我收到错误:

  

不是功能

但是如果我从父组件中调用相同的函数,它的工作正常。你可以看到我的代码我从子组件调用函数this.props.toggle(),它与父组件中的toggleCallModel函数相对应。

Here is my code : 

    Child Component : 
    import React from 'react';
    import Dialog from 'material-ui/Dialog';
    import FlatButton from 'material-ui/FlatButton';
    import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
    import Avatar from "material-ui/Avatar";

    /**
     * A modal dialog can only be closed by selecting one of the actions.
     */

    class CallModal extends React.Component {

        constructor(props) {
            super(props);
            this.state = {
                open: props.open,
                title: props.title,
                conn: props.conn,
                buttonLabel: "HangUp",
                callTime: 0,
            };
            this.pickCall = this.pickCall.bind(this);
            this.pickCancel = this.pickCancel.bind(this);
            this.hangUp = this.hangUp.bind(this);
            this.handle = this.handle.bind(this);
        }

        componentWillMount() {
            let self = this;
            let callProgressInterval = null;
            this.setState({
                buttonLabel: (!ValuexSDK.getInstance().isCallActive() && !ValuexSDK.getInstance().isCaller()) ? "Accept" : "HangUp"
                ,
                title: ValuexSDK.getInstance().isCallActive() ? "Call in-progress.." : (ValuexSDK.getInstance().isCaller() ? "Calling.." : "Incoming call..")
            });
            ValuexSDK.getInstance().subscribeEvents("onConnect", function () {
                self.setState({buttonLabel: "HangUp", title: "Call in-progress.."});
                self.updateCallTime(self, callProgressInterval);
            });

            ValuexSDK.getInstance().subscribeEvents("onDisConnect", function () {
                self.props.toggle(false);
                self.setState({buttonLabel: "Accept"});
                clearInterval(callProgressInterval);
            });

            ValuexSDK.getInstance().subscribeEvents("onCancel", function () {
                self.props.toggle(false);
                self.setState({buttonLabel: "Accept"});
            });
        }

        updateCallTime(self, callProgressInterval) {
            callProgressInterval = setInterval(function () {
                self.setState({
                    callTime: ValuexSDK.getInstance().getCallTime(),
                });
            }, 1000);
        }

        componentWillReceiveProps(props) {
            this.setState({open: props.open});
            this.setState({
                buttonLabel: (!ValuexSDK.getInstance().isCallActive() && !ValuexSDK.getInstance().isCaller()) ? "Accept" : "HangUp"
                ,
                title: ValuexSDK.getInstance().isCallActive() ? "Call in-progress.." : (ValuexSDK.getInstance().isCaller() ? "Calling.." : "Incoming call..")
            });
        }

        pickCall() {
            ValuexSDK.getInstance().accept(this.props.conn);
        };

        pickCancel() {
            ValuexSDK.getInstance().reject(this.props.conn);
            this.props.toggle(false);
        };

        handle() {
            (!ValuexSDK.getInstance().isCallActive() && !ValuexSDK.getInstance().isCaller()) ?
                this.pickCall() : this.hangUp();

        };

        hangUp() {
            ValuexSDK.getInstance().disconnectAll();
            this.props.toggle(false);
        };

        render() {
            const closeImg = {cursor: 'pointer', float: 'right', marginTop: '5px', width: '20px'};

            const actions = [
                <FlatButton
                    label={this.state.buttonLabel}
                    primary={true}
                    onClick={this.handle}
                />
            ];

            if (!ValuexSDK.getInstance().isCallActive() && !ValuexSDK.getInstance().isCaller()) {
                actions.push(<FlatButton
                    label="Reject"
                    primary={true}
                    onClick={this.pickCancel}
                />);
            }

            let style = {};

            if (undefined !== ValuexSDK.getInstance().getStyle()) {
                style.backgroundColor = ValuexSDK.getInstance().getStyle().primaryColor;
                style.color = ValuexSDK.getInstance().getStyle().primaryTextColor
            }

            let callerPic = ValuexSDK.getInstance().getCaller() ?
                ValuexSDK.getInstance().getCaller()['profile_pic'] : '';

            let calleePic = ValuexSDK.getInstance().getCallee() ?
                ValuexSDK.getInstance().getCallee()['profile_pic'] : '';

            let callerName = ValuexSDK.getInstance().getCaller() ?
                ValuexSDK.getInstance().getCaller()['name'] : '';

            let calleeName = ValuexSDK.getInstance().getCallee() ?
                ValuexSDK.getInstance().getCallee()['name'] : '';

            return (
                <MuiThemeProvider>
                    <div>
                        <Dialog className="vx-call-dialog"
                                titleClassName="va-call-dialog-title"
                                title={<div>
                                    {this.state.title}
                                    {ValuexSDK.getInstance().isCallActive() ?
                                        <img onClick={() => this.props.toggle(false)}
                                             src='https://d30y9cdsu7xlg0.cloudfront.net/png/53504-200.png'
                                             style={closeImg}/> : ''}
                                </div>}
                                titleStyle={style}
                                actions={actions}
                                modal={true}
                                open={this.state.open}
                        >
                            <div>
                                <div className="va-call-dialog-avatar-box"><Avatar size={60}
                                                                                   src={callerPic}/>
                                    <h4>{callerName}</h4></div>
                                <div className="va-call-dialog-avatar-box" style={{marginTop: '50px'}}>
                                    <p>{this.state.callTime}</p>
                                    =========>
                                </div>
                                <div className="va-call-dialog-avatar-box"><Avatar size={60}
                                                                                   src={calleePic}/>
                                    <h4>{calleeName}</h4></div>
                            </div>
                        </Dialog>

                    </div>
                </MuiThemeProvider>
            );
        }
    }


    export default CallModal;

    Parent Compoent : 

    import React from 'react';
    import './service/src/sdk.js';
    import OnlineList from "./view/List";
    import {ValuexSDK} from "./service/src/sdk";
    import {Section} from "./view/Common";
    import OnlineUsers from "./OnlineUsers";
    import CallModal from "./service/src/CallModal";


    // Container
    class App extends React.Component {
        constructor(props) {

            super(props);
            this.state = {
                showOnlineUser : false,
                showCallModel : false
            };

            this.toggleOnlineUser = this.toggleOnlineUser.bind(this);
            this.toggleCallModel = this.toggleCallModel.bind(this);

        }

        toggleOnlineUser(value) {
            this.setState({showOnlineUser:value});
        }

        toggleCallModel(value) {
            this.setState({showCallModel:value});
        }

        render() {
            let style = {};

            if (undefined !== ValuexSDK.getInstance().getStyle()) {
                style.backgroundColor = ValuexSDK.getInstance().getStyle().primaryColor;
                style.color = ValuexSDK.getInstance().getStyle().primaryTextColor
            }

            return (<div>
                    <CallModal open={this.state.showCallModel}
                               toggle={this.toggleCallModel}/>
                    <OnlineUsers open={this.state.showOnlineUser}
                                 toggleOnlineUser={this.toggleOnlineUser}/>
                </div>
            );
        };
    }

    export default App;

1 个答案:

答案 0 :(得分:0)

将this.state.showOnlineUser更改为this.state.showOnlineUser()。它会完美地运作。