I'm trying to implement hide/show button in react 16
If I click a button then it should show Card
button , if i click card
button it should hide card
button, I have implemented this but I have used componentwillReceiveprops
props which is not recommended in react 16 I tried static getDerivedStateFromProps
but it gets called when I do setState
in handleclick
working js fiddle
how can i achieve the same result without using componentwillReceiveprops
below is my code
class Test extends React.Component {
state ={
show: false
}
show(){
this.setState({show: true})
}
render() {
return (
<div className="App">
<button onClick={this.show.bind(this)}>show the button</button>
{this.state.show && <Notification show={true}/>}
</div>
)
}
}
const style = {
marginBottom: '0.5rem',
float: 'right',
boxShadow: '0 4px 8px 0 rgba(0, 0, 0, 0.1)',
marginTop: '-9px'
};
class Notification extends React.Component {
constructor(props){
super(props);
this.state ={
open: true
}
}
componentWillReceiveProps(props){
console.log('will recieve props')
this.setState({open: props.show})
}
handleClick(){
this.setState({open: false})
}
render(){
if(!this.state.open){
return null
}
return (
<div className="test">
<div>
<button onClick={()=>this.handleClick()}>Card</button>
</div>
</div>
)
}
};
ReactDOM.render(
<Test name="World" />,
document.getElementById('container')
);
Instead of making it complicated, keep it simple and use toggleShow
on the parent component and only mount Notification
if show is true, pass in toggleShow
from the parent as props to be able to toggle it from our child component
class Test extends React.Component {
constructor() {
super();
this.state = { show: false };
this.toggleShow = this.toggleShow.bind(this);
}
toggleShow() {
this.setState(prevState => ({ show: !prevState.show }));
}
render() {
return (
<div className="App">
<button onClick={this.toggleShow}>show the button</button>
{this.state.show && <Notification hideNotification={this.toggleShow} />}
</div>
);
}
}
const Notification = ({ hideNotification }) => (
<div className="test">
<div>
<button onClick={hideNotification}>Card</button>
</div>
</div>
);
This is one of those cases where using hooks will make the syntax really terse:
import React, { useState } from "react";
import ReactDOM from "react-dom";
const Test = () => {
const [show, setShow] = useState(false)
return (
<div className="App">
<button onClick={() => { setShow(true) }}>show the button</button>
{
show &&
<Notification handleClick={() => { setShow(false) }}/>
}
</div>
)
}
const Notification = ({handleClick}) => (
<div className="test">
<div>
<button onClick={handleClick}>Card</button>
</div>
</div>
)
But the substance is similar to https://stackoverflow.com/a/55673710/2417031 .
I am writing two solutions one that uses "open state and getDerivedStateFromProps lifecycle method" and another one that doesn't use "open state and getDerivedStateFromProps lifecycle method".
class Test extends Component {
state ={
show: false
}
constructor(props) {
super(props);
this.closeShow = this.closeShow.bind(this);
}
show(){
this.setState({show: true})
}
render() {
return (
<div className="App">
<button onClick={this.show.bind(this)}>show the button</button>
{this.state.show && <Notification show={true} onClose={this.closeShow} />}
</div>
)
}
closeShow(e) {
e.preventDefault();
this.setState({show:false});
}
}
and Notification Component as:
class Notification extends Component {
constructor(props){
super(props);
this.state ={
open: true
}
}
static getDerivedStateFromProps(nextProps, prevState){
if (nextProps.show !== prevState.open) {
return {open: nextProps.show};
}
return null;
}
render(){
const {onClose} = this.props;
if(!this.state.open){
return null
}
return (
<div className="test">
<div>
<button onClick={onClose}>Card</button>
</div>
</div>
)
}
}
Only Notification component requires change as shown:
class Notification extends Component {
render(){
const {show, onClose} = this.props;
if(!show){
return null
}
return (
<div className="test">
<div>
<button onClick={onClose}>Card</button>
</div>
</div>
)
}
}
With Solution 2 we can use the stateless component as there is no state to manage and stateless components render fastly as compare to stateful components. Code for the stateless component is as:
const Notification = function(props) {
const {show, onClose} = props;
if(!show){
return null
}
return (
<div className="test">
<div>
<button onClick={onClose}>Card</button>
</div>
</div>
)
}
It is better to follow the 2nd solution as, when the show state of click button is managed from the Test component's "show" state variable then the hide state of the click button must also be managed from the Test component's "show" state variable.
I have given solution 1 just to have an understanding of getDerivedStateFromProps lifecycle method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.