David Johns
David Johns

Reputation: 1714

How to update props immediately when updating states in react?

I'm creating a react app with a parent dashboard component and a child modal component. I have a button in another child component and I'm getting an ID from that button click and firing a function in the Parent dashboard component. I'm setting a state in that function and send the state as props from the Parent dashboard component to the Child modal component to open the modal and show the ID inside the modal body. The problem is, I need to click twice to open the model and need to click twice to close the modal. I know that I need to use state callback method but not sure how to.

Parent Dashboard component:

import ProjectModal from './projectModal';
import Card from './card';

class Dashboard extends Component {
  constructor(props) {
    super(props);
    this.state = {
      currentId: '',
      open: false
    };
  }

  handleClose = () => {
    this.setState({ open: false });
  };

  getPojectId = (projectId) => {
    this.setState({
      open: true,
      currentId: projectId
    })
  }

  render(){
    return(
      <ProjectModal
         handleOpen={this.state.open}
         handleClosed={this.handleClose}
         projectID={this.state.currentId}
      />
      <Card getCardId={this.getPojectId} />
    )
  }
}

Child modal component:

class ProjectModal extends Component {
    constructor(props) {
        super(props);
        this.state = {
            open: false,
            currentId: ''
        };
    }

    componentWillReceiveProps() {
        this.setState({
            open: this.props.handleOpen,
            currentId: this.props.projectID
        })
    }

    render() {

        return (
            <div className="projectDetailsModal">
                <Dialog
                    open={this.state.open}
                    keepMounted
                    onClose={this.props.handleClosed}
                    aria-labelledby="form-dialog-slide-title"
                    aria-describedby="form-dialog-slide-description"
                >
                    <div className="modalClose" onClick={this.props.handleClosed}>
                        <span>&times;</span>
                    </div>
                    <DialogContent>
                        <div className="centerModal">
                            <div className="projectFormHeader">ID {this.state.currentId}</div>
                        </div>
                    </DialogContent>
                </Dialog>
            </div>
        );
    }
}

Upvotes: 0

Views: 755

Answers (3)

Paveloosha
Paveloosha

Reputation: 623

"Ilsanchez" is right. Also you don't need to make 'Child modal' as class component, it could be functional only.

Upvotes: 0

kkangil
kkangil

Reputation: 1746

what about try to use newProps parameter?

componentWillReceiveProps(newProps) {
  if (newProps.handleOpen !== this.props.handleOpen) {
       this.setState({
            open: this.props.handleOpen,
            currentId: this.props.projectID
        })
  }
 }

current value is this.props.handleOpen , new changed value is newProps.handleOpen.

Upvotes: 0

Ilsanchez
Ilsanchez

Reputation: 271

You should avoid the use of componentWillReceiveProps, its use is discouraged. And in other hand, copy props into state is an antipattern, in your code there arent any need to do it.

In your Dashboard component try this:


constructor(props) {
    super(props);
    this.state = {
      currentId: '',
      open: false
    };
    this.handleClose = this.handleClose.bind(this);

And, in your Modal, first remove State, you don't need in this component, its pure. Before that, changes all your this.state to this.props.

Upvotes: 2

Related Questions