1. 需求背景
在开发React项目时,想自己封装一个Modal弹窗。在父组件中调用弹窗控制展示和隐藏。当点击子组件的关闭按钮时,调用父组件中定义的关闭弹窗方法。这样可以在关闭弹窗时有一些自定义操作。
2. 问题呈现结果
父组件定义好的弹窗关闭方法:
closeAnswerModal = () => {
this.setState({
showModal: false
})
}
当我在子组件中调用父组件定义好的弹窗关闭方法时,根据打印日志我们不难发现,当我们第一次点击的时候,这个值并没有被成功修改,第二次时才将这个弹窗关闭
3. 原因
- 判断出现问题原因,我在子组件中监听数据变化用的是componentDidUpdate
componentDidUpdate(props, state) {
console.log(props.show, 'props.show', state.showModal, 'state.showModal')
if(props.show !== state.showModal) {
this.setState({
showModal: props.show
})
}
}
此时在里面打印接收到的props.show控制弹窗展示关闭的这个值发现,点击第一次的时候接收到的props值并不正确,所以推测选用生命周期方法是有问题的
4. 修改方式
- 于是将componentDidUpdate 改为了
getDerivedStateFromProps
static getDerivedStateFromProps = (props, state) => {
console.log(props.show)
if(props.show !== state.showModal) {
return {
showModal: props.show
}
}
return null
}
不要在这个方法中使用this.setState赋值,直接在return中赋值可以达到相同的效果,发现问题已经被解决啦,原来是使用有误哦
5. 全部代码
import { Component } from "react";
import './index.scss'
export default class Modal extends Component {
constructor(props) {
super(props)
this.state = {
showModal: false
}
}
static getDerivedStateFromProps = (props, state) => {
console.log(props.show)
if(props.show !== state.showModal) {
return {
showModal: props.show
}
}
return null
}
render() {
return (
<div className="toast_container">
{
this.state.showModal && (
<div>
<div className="toast_content">
<div className="toast_content_top">
<h2 className="toast_content_top_name">{this.props.title}</h2>
<img className="toast_content_top_icon"
src={require('../../assets/images/close.png')} alt="关闭"
onClick={this.props.closeModal}
/>
</div>
<p className="toast_content_bottom">{this.props.content}</p>
</div>
<div className="toast_overlay" />
</div>
)
}
</div>
)
}
}
import Modal from "../../components/Modal";
closeAnswerModal = async () => {
this.setState({
showModal: false
})
}
<Modal
show={this.state.showModal}
title="提示"
content="?选择正确"
closeModal={this.closeAnswerModal}
/>
6. 总结
- 子组件中定义组件内容,并定义展示条件值
- 父组件传入值控制子组件的展示与隐藏,子组件通过
static getDerivedStateFromProps 实时监听值的变化赋值 - 父组件将控制弹窗关闭的方法定义好,传给子组件
- 子组件通过
this.props.[父组件传入的方法] 进行调用
如果有用,点个赞呗~
总结用法,希望可以帮助到你, 我是Ably,你无须超越谁,只要超越昨天的自己就好~
|