我正在尝试在react 16
中实现隐藏/显示按钮如果我点击一个按钮然后它应该显示Card
按钮,如果我点击card
按钮它应该隐藏card
按钮,我已经实现了这个但我已经使用了componentwillReceiveprops
道具,这是不推荐的反应16我尝试了static getDerivedStateFromProps
,但当我在setState
handleclick
做working js fiddle时它被调用
如何在不使用componentwillReceiveprops
的情况下实现相同的结果
下面是我的代码
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')
);
不要让它变得复杂,保持简单并在父组件上使用toggleShow
并且如果show为true则仅挂载Notification
,从父级传递toggleShow
作为props,以便能够从我们的子组件切换它
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>
);
这是使用hooks将使语法真正简洁的情况之一:
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>
)
我正在编写两个使用“open state和getDerivedStateFromProps生命周期方法”的解决方案,另一个不使用“open state和getDerivedStateFromProps生命周期方法”的解决方案。
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});
}
}
和通知组件为:
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>
)
}
}
只有通知组件需要更改,如下所示:
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>
)
}
}
使用解决方案2,我们可以使用无状态组件,因为与有状态组件相比,没有状态可以管理,无状态组件可以快速呈现。无状态组件的代码如下:
const Notification = function(props) {
const {show, onClose} = props;
if(!show){
return null
}
return (
<div className="test">
<div>
<button onClick={onClose}>Card</button>
</div>
</div>
)
}
最好遵循第二种解决方案,因为当从Test组件的“show”状态变量管理单击按钮的显示状态时,还必须从Test组件的“show”状态变量管理单击按钮的隐藏状态。
我已经给出了解决方案1,只是为了了解getDerivedStateFromProps生命周期方法。