Shoaib Iqbal
Shoaib Iqbal

Reputation: 2730

Pass props to child component from parent component dynamically

I have a child component StepperNotification which gets an input from user and returns it as prop to its child component in following way.

const styles = {
    transparentBar: {
        backgroundColor: 'transparent !important',
        boxShadow: 'none',
        paddingTop: '25px',
        color: '#FFFFFF'
    }
};


const useStyles = makeStyles((theme: Theme) =>
    createStyles({
        formControl: {
            margin: theme.spacing(1),
            minWidth: 120,
        },
        selectEmpty: {
            marginTop: theme.spacing(2),
        },
    }),
);

function getSteps() {
    return ['Create', 'Audience', 'Timing'];
}

function getStepContent(step, $this) {


    switch (step) {
        case 0:
            return (
                <div className="row">
                    <CardBox styleName="col-lg-12"
                             heading="">
                        <form className="row" noValidate autoComplete="off" style={{"flex-wrap":"no-wrap", "flex-direction": "column" }}>
                            <div className="col-md-12 col-12">
                                <TextField
                                    id="campaign_name"
                                    label="Campaign Name"
                                    value={$this.state.name}
                                    onChange={$this.handleChange('name')}
                                    margin="normal"
                                    fullWidth
                                />
                            </div>
                        </form>
                    </CardBox>
                    
                </div>
                );
        default:
            return 'Unknown step';
    }
}

class NotificationStepper extends React.Component {
    state = {
        activeStep: 0,
        name: '',
    };

    handleChange = name => event => {
        this.setState({
            [name]: event.target.value,
        });
        this.props.titlechange(event.target.value);
    };


    handleNext = () => {
        this.setState({
            activeStep: this.state.activeStep + 1,
        });
    };

    handleBack = () => {
        this.setState({
            activeStep: this.state.activeStep - 1,
        });
    };

    handleReset = () => {
        this.setState({
            activeStep: 0,
        });
    };

    render() {
        const steps = getSteps();
        const {activeStep} = this.state;

        return (
            <div className="col-xl-12 col-lg-12 col-md-7 col-12">
                <Stepper className="MuiPaper-root-custom" activeStep={activeStep} orientation="vertical">
                    {steps.map((label, index) => {
                        return (
                            <Step key={label}>
                                <StepLabel>{label}</StepLabel>
                                <StepContent className="pb-3">
                                    <Typography>{getStepContent(index, this)}</Typography>
                                    <div className="mt-2">
                                        <div>
                                            <Button
                                                disabled={activeStep === 0}
                                                onClick={this.handleBack}
                                                className="jr-btn"
                                            >
                                                Back
                                            </Button>
                                            <Button
                                                variant="contained"
                                                color="primary"
                                                onClick={this.handleNext}
                                                className="jr-btn"
                                            >
                                                {activeStep === steps.length - 1 ? 'Finish' : 'Next'}
                                            </Button>
                                        </div>
                                    </div>
                                </StepContent>
                            </Step>
                        );
                    })}

                </Stepper>
                {activeStep === steps.length && (
                    <Paper square elevation={0} className="p-2">
                        <Typography>All steps completed - you&quot;re finished</Typography>
                        <Button onClick={this.handleReset} className="jr-btn">
                            Reset
                        </Button>
                    </Paper>
                )}


            </div>

        );
    }
}

export default NotificationStepper;

In my parent component i am getting this prop value and passing it to another child component Tabcomponent in following way

ParentCompoennt.js

const SendNotification = ({match}) => {

    let titlename = '';
    let message = '';

    function handleTitle(title_) {
        console.log('in here');
        console.log(title_);
        titlename = title_;
    }
    return (

        <div className="dashboard animated slideInUpTiny animation-duration-3">

            <ContainerHeader match={match} title={<IntlMessages id="sidebar.notification"/>}/>
            <div className="row" style={{'flex-wrap': 'no wrap', "flex-direction": 'row'}}>

                <div className="col-xl-7 col-lg-7 col-md-7 col-7">

                    <NotificationStepper titlechange={handleTitle} />
                    <div className='flex-class' style={{'width': '100%'}}>
                        <Button color="primary" style={{"align-self": "flex-end", "border" : "1px solid", "margin-left": "10px", "margin-bottom": "40px"}} size="small" className="col-md-2 col-2">Fetch</Button>
                        <Button color="primary" style={{"align-self": "flex-end", "border" : "1px solid", "margin-left": "10px", "margin-bottom": "40px"}} size="small" className="col-md-2 col-2" color="primary">Discard</Button>
                    </div>
                </div>
                <div className="col-xl-5 col-lg-5 col-md-5 col-5" style={{"padding-top": "20px"}}>
                    <span style={{"margin-left" : "20px", "font-weight": "bold"}}>Preview</span>
                    <TabComponent  {...{[title]:titlename}} message={message} />
                </div>

            </div>

        </div>
    );
};

export default SendNotification;

and in TabComponent i am getting this prop value and using it component in following way

TabContainer.propTypes = {
    children: PropTypes.node.isRequired,
    dir: PropTypes.string.isRequired,
};

class TabComponent extends Component {
    state = {
        value: 0,
    };


    render() {
        const {theme} = this.props;
        const title = this.props.title;


        return (
            <div className="col-xl-12 col-lg-12 col-md-12 col-12" style={{"margin-top": "15px"}}>
                    <NotifCard  key={0} data={{'name': title, 'company': 'sayge.ai', 'image': require("assets/images/bell.png"), 'description': this.props.message}} styleName="card shadow "/>
                    
            </div>
        );
    }
}

TabComponent.propTypes = {
    theme: PropTypes.object.isRequired,
};

export default withStyles(null, {withTheme: true})(TabComponent);

StepperNotification is working fine and props are being updated in parent. i have checked this by printing the updated values in console, but the props in TabComponent are not being updated. What am i doing wrong here? any help is appreciated.

Upvotes: 1

Views: 847

Answers (1)

Xesenix
Xesenix

Reputation: 2548

Probaly this is your issue

<TabComponent  {...{[title]:titlename}} message={message} />` this could be just 

title is undefined and you are sending props[undefined]=titlename

Just do this

<TabComponent title={titlename} message={message} />`

And if SendNotification is react fuction component useState for keeping track of current titlename. If it still doesn't work after first fix this second will be another source of your problems.

Upvotes: 0

Related Questions