Reputation: 363
I have a problem with update props.
I have two components.
The first is the App, where there is a button that opens or closes the modal.
The second is the modal structure.
The first component stores the state, I click the buton, the state changes, I send props to ModalComponent
component (the modal is opening).
And in this component should change this state if I want to close modal.
But if I click on the Cancel
button in modal, nothing happens.
The state does not change.
How to change it, how it would make communication between the child and the parent?
This is my code :
ModalComponent
import React, { Component } from "react";
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
class ModalComponent extends Component {
constructor(props) {
super(props);
this.state = {
modal: props.modal
};
this.toggle = this.toggle.bind(this);
}
toggle() {
const { modal } = this.state;
this.setState({
modal: !modal
});
}
render() {
const { modal } = this.props;
return (
<div>
<Modal isOpen={modal} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>Halo</ModalHeader>
<ModalFooter>
<Button onClick={this.toggle}>Cancel</Button>
</ModalFooter>
</Modal>
</div>
);
}
}
export default ModalComponent;
App
import React from "react";
import ReactDOM from "react-dom";
import Modal from "./modal";
import { Button } from "reactstrap";
import "./styles.css";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
modal: false
};
this.toggle = this.toggle.bind(this);
}
toggle() {
const { modal } = this.state;
this.setState({
modal: !modal
});
}
render() {
const { modal } = this.state;
return (
<div>
<Button
type="link"
onClick={this.toggle}
>
Delete account
</Button>
<Modal modal={modal} />
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Upvotes: 0
Views: 2145
Reputation: 282030
The state in your Modal Component would change but you aren't using it to set the isOpen
props on Modal
component.
Also you must not use state which is directly derivable from props. You must instead pass a handler from Parent to update the state in the parent itself
ModalComponent
import React, { Component } from "react";
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
class ModalComponent extends Component {
render() {
const { modal } = this.props;
return (
<div>
<Modal isOpen={modal} toggle={this.toggle}>
<ModalHeader toggle={this.props.toggle}>Halo</ModalHeader>
<ModalFooter>
<Button onClick={this.props.toggle}>Cancel</Button>
</ModalFooter>
</Modal>
</div>
);
}
}
export default ModalComponent;
App
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
modal: false
};
this.toggle = this.toggle.bind(this);
}
toggle() {
const { modal } = this.state;
this.setState({
modal: !modal
});
}
render() {
const { modal } = this.state;
return (
<div>
<Button
type="link"
onClick={this.toggle}
>
Delete account
</Button>
<Modal modal={modal} toggle={this.toggle}/>
</div>
);
}
}
Upvotes: 2
Reputation: 17269
The way you have it now, the modal is setting its own state, but it is still receiving a prop from the parent, which is keeping it open.
Here's an example of one way to do it. Note that both opening and closing is dealt with using the state of the parent, not the state of the child.
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class App extends React.Component {
state = { open: false };
toggle = () => {
this.setState({ open: !this.state.open });
};
render() {
return (
<React.Fragment>
something
<Modal show={this.state.open} />
<Child toggle={this.toggle} />
</React.Fragment>
);
}
}
const Child = ({ toggle }) => {
return <button onClick={toggle}>toggle</button>;
};
const Modal = ({ show }) => {
if (show) {
return <h1>I am a modal</h1>;
}
return null;
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
CodeSandbox here.
Upvotes: 0