Search code examples
reactjscomponents

Adding and Removing Components React


I am building a product card with a 'Open Form' Button. What is want to do is when I click on Open Form , a form to be displayed and when I click on cross it should be hidden. I am doing this by using components.

Issue - I click on Open Form, form gets displayed then I click on cross, it then hides but when I click again on the button it is not being displayed. I have used state variables to render component, when I debugged, the updated state is maintained.

Code - (ProdCard Class)

import React from 'react';
import ReactDOM from 'react-dom';
import FormLayout from '../Form/FormLayout';
import {Atag,Button, Container} from '../Elements/Elements';

class ProdCard extends React.Component {
    constructor(props){
        super(props);
        this.openForm = this.openForm.bind(this);
    }
    openForm(){
        ReactDOM.render(<FormLayout ctaClicked={true}/>, document.getElementById('forms'));
    }
    render() {
      return(
            <Container className="prodBox pdiBox pdiDf pdiFdc">
                <Container className="pdiPrd pdiDf">
                    <Atag href="" className="pdiImg pdiDf" children={<img alt={this.props.ProdName}/>}/>
                    <Container>
                        <h2><Atag href="" className="pdiDf pdiClr1" children={this.props.ProdName}/></h2>
                        <h3><Atag href="" className="pdiDf" children={this.props.ProdName}/></h3>
                        <Button className="gbp" id={this.props.id} onClick={this.openForm} children="Get Best Price"/>
                    </Container>
                </Container>
                <Container className="pdiDtls pdiFdc">
                    <p className="pdiTal">{this.props.Desc}</p>
                    <Atag href="#" children="View Details"/>
                 </Container>
            </Container>
      )
    }
}

export default ProdCard;

Code - (FormLayout Class)

import React from 'react';
import ReactDOM from 'react-dom';
import { Container } from '../Elements/Elements';
import FormLeft from '../Form/FormLeft';
import FormRight from '../Form/FormRight';

class FormLayout extends React.Component{
    constructor(props){
        super(props);
        this.state = {showForm : true, isCloseClicked : false}
        this.removeForm = this.removeForm.bind(this);
        this.showForm = this.showForm.bind(this);
    }
    removeForm(){
        this.setState({showForm : false, isCloseClicked : true})
    }
    render(){
        if(this.state.showForm === false) return <Container/>
        else
        return(
            <Container>
                <Container className="blck"></Container>
                <Container className="forms bcp bc">
                    <Container id="left" className="ls bcl"/>
                    <Container  className="rs">
                        <Container children="X" className="close" onClick={this.removeForm}/>
                        <Container id="right"/>
                    </Container>
                </Container>
            </Container>
             
        );
    }
    componentDidMount(){
        ReactDOM.render(<FormLeft/>, document.getElementById('left'));
        ReactDOM.render(<FormRight/>, document.getElementById('right'));
    }
}

export default FormLayout;

When exactly can I update the state to achieve "user clicks on form , it displays , user clicks on cross it hides (and this can happen a million times)" ?

New to React, a little connfused.


Solution

  • Your code looks weird and does not like the React's way, please don't use React.render directly, you should let ProdCard control whether to display the FormLayout

    you should change your code to this:

    class ProdCard extends React.Component {
        constructor(props){
            super(props);
            this.openForm = this.openForm.bind(this);
            this.state = { showForm: true }
        }
        openForm(){
            this.setState({ showForm: true })
        }
        closeForm() {
            this.setState({ showForm: false })
        }
        render() {
          return(
            <>
              <Container className="prodBox pdiBox pdiDf pdiFdc">
                  <Container className="pdiPrd pdiDf">
                      <Atag href="" className="pdiImg pdiDf" children={<img alt={this.props.ProdName}/>}/>
                      <Container>
                          <h2><Atag href="" className="pdiDf pdiClr1" children={this.props.ProdName}/></h2>
                          <h3><Atag href="" className="pdiDf" children={this.props.ProdName}/></h3>
                          <Button className="gbp" id={this.props.id} onClick={this.openForm} children="Get Best Price"/>
                      </Container>
                  </Container>
                  <Container className="pdiDtls pdiFdc">
                      <p className="pdiTal">{this.props.Desc}</p>
                      <Atag href="#" children="View Details"/>
                   </Container>
              </Container>
              <FormLayout visible={this.state.showForm} onClose={this.closeForm} />
            </>
          )
        }
    }
    
    class FormLayout extends React.Component{
        constructor(props){
            super(props);
        }
        render(){
            if(!this.props.visible) {
              return <Container/>
            }
    
            return(
                <Container>
                    <Container className="blck"></Container>
                    <Container className="forms bcp bc">
                        <Container id="left" className="ls bcl">
                          <FormLeft/>
                        </Container>
                        <Container  className="rs">
                            <Container children="X" className="close" onClick={this.props.closeForm}/>
                            <Container id="right">
                              <FormRight/>
                            </Container>
                        </Container>
                    </Container>
                </Container>
            );
        }
    }