3

I have a situation here where I cannot render my child component ModalConatiner from my parent. I would however like to mention that there is a chain of parent child components before and after this piece.I have imported it as well.

 getAssetDocId(e) {
        var assetDocId = e.currentTarget.attributes['id'].value;
        var assetDBId = e.currentTarget.attributes['dbId'].value;
        var code = e.currentTarget.attributes['code'].value;

        console.log('----------------------------------------------------');
        return <ModalContainer assetDocId={assetDocId} assetDBId={assetDBId} code={code} defaultValues={this.props.defaultValues} allAssetDetails={this.props.allAssetDetails} />
     }

called by

<div className="card-overlay modal-trigger"  data-target="asset-detail" id={asset.docId} dbId={asset.dbId} code={asset.code} key={asset.docId} onClick={this.getAssetDocId}>

The child component -

import React, { Component } from 'react';
import {Button, Icon, Row, Col, Carousel, Chip, Collapsible, CollapsibleItem, Input, Dropdown, NavItem, Form, Modal} from 'react-materialize';
import AssetDetails from './../assetlisting/assetdetails.jsx';

class ModalContainer extends Component {
    constructor(props) {
        super(props);
        this.resetValues = this.resetValues.bind(this);
        this.resetAssetValues = React.createRef();
        this.renderAssetDetails = this.renderAssetDetails.bind(this);
    }

    renderAssetDetails() {

        return <AssetDetails assetDocId={this.props.assetDocId} assetDBId={this.props.assetDBId} code={this.props.code} defaultValues = {this.props.defaultValues} ref={this.resetAssetValues} allAssetDetails={this.props.allAssetDetails}/>;
    }

    resetValues = () => {
        this.resetAssetValues.current.showInfo();
    };

    render() {
        console.log('ppppppppppppppppppppppppppppppp');

        return (
            <div>
                <Modal id="asset-detail" className="fullscreen"
                       modalOptions={{preventScrolling: true}}>
                    <div className="modal-content">
                        <div className="asset-details">
                            <div className="modal-close waves-effect" onClick={this.resetValues}>
                                <i className="material-icons">close</i>
                            </div>
                            { this.renderAssetDetails() }
                        </div>
                    </div>
                </Modal>
            </div>
        )
    }
}
export default ModalContainer;

Can somebody please point out what is the issue here?

9
  • onClick={(e) => this.getAssetDocId(e)}> Commented Sep 24, 2018 at 10:08
  • @LazarNikolic It still doesn't work.I think there is some issue with the child component not being rendered. Commented Sep 24, 2018 at 10:10
  • Do you get ----------- in console? Commented Sep 24, 2018 at 10:11
  • Yes I do get it Commented Sep 24, 2018 at 10:13
  • Do you want to have a look at the MOdalContainer component? @LazarNikolic Commented Sep 24, 2018 at 10:13

2 Answers 2

2

What you need to do is to render child component is

Check below code for better understanding. This is how you can implement your functionality

constructor(props){
   super(props);
   this.state = {
      assetDocId: "",
      assetDBId: "",
      code: "",
      showModalContainer: false
   }
}

getAssetDocId = e => {
     this.setState({
        assetDocId:e.currentTarget.attributes['id'].value,
        assetDBId: e.currentTarget.attributes['dbId'].value,
        code: e.currentTarget.attributes['code'].value,
        showModalContainer: true
     })
}

render(){
    const {assetDocId, assetDBId, code, showModalContainer} = this.state;
    return(
      <div>
        {showModalContainer && <ModalContainer assetDocId={assetDocId} assetDBId={assetDBId} code={code} defaultValues={this.props.defaultValues} allAssetDetails={this.props.allAssetDetails} />}
      </div>
    )
}

There are many ways to do the same.

Sign up to request clarification or add additional context in comments.

1 Comment

The modal appears only after the second time it is clicked, the first time the console ppppppppppppppp comes but not the popup modal.I believe it has got to do something with the state not getting set instantly after the first click.Could it be?
0

onClick method doesn't do anything with the returned value, since your are returning the modal container from the getAssetDocId method, it won't work, you instead need to set a state and render the ModalContainer based on the state value

getAssetDocId(e) {
        var assetDocId = e.currentTarget.attributes['id'].value;
        var assetDBId = e.currentTarget.attributes['dbId'].value;
        var code = e.currentTarget.attributes['code'].value;
        this.setState({
            assetDocId, 
            assetDBId,
            code,
            showModal: true
        })
     }

render() {
    const { assetDocId, assetDBId, code, showModal } = this.state;
    return (
       <React.Fragment>
           <div className="card-overlay modal-trigger"  data-target="asset-detail" id={asset.docId} dbId={asset.dbId} code={asset.code} key={asset.docId} onClick={this.getAssetDocId}>
           {showModal && <ModalContainer assetDocId={assetDocId} assetDBId={assetDBId} code={code} defaultValues={this.props.defaultValues} allAssetDetails={this.props.allAssetDetails} />}
       </React.Fragment>
    )
}

3 Comments

can you please explain as to what is the flaw in the current approach and why is the new one better,or is it just how it is done?
@SHIKHARSINGH when onClick triggers the component won't re-render in your case and also since you are using regular function this won't be available inside the function untill and unless you assign this to a local variable like self for eg. Because of these reasons child component isn't rendering
@SHIKHARSINGH, as I mentioned in my answer, the JSX returned to onClick isn't really processed by it and hence your content won't render, you need to render your content in the render function itself. The best way to do it is to have a boolean to show/hide the Component

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.