React中封装Modal组件为子组件,可多次复用。子组件的Modal是否显示,取决于父组件的props。
涵盖知识点:state由父组件传入、组件的封装、antd中Modal组件的应用。
本文还包括:在子组件中如何调用父组件的方法
效果:点击父组件的Button按钮,将渲染包含Modal的子组件,弹出对话框,保证多次点击都有效。(可能出现的问题,第一次有效,之后多次点击无法弹出对话框。要保证state的变化,正确渲染页面。)
componentWillReceiveProps起关键作用:将props转换成自己的state
AA是父组件中自定义的函数名,在子组件中通过this.props.AA()可调用。如果在父组件中传参,只需要处理父组件中的这个带参函数的逻辑即可。子组件只负责直接调用。
父组件:
import React from 'react';
import 'antd/dist/antd.css';
import { Button } from 'antd';
import D from './components/D'; // 引入子组件D
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
flag: false // 初始为false
}
}
// 点击后改为true 渲染D组件
fun = () => {
this.setState({
flag: true
}, () => {
console.log('APP state flag ', this.state.flag)
}) // 回调函数
}
//父组件的方法AA的执行函数,代码块内容只是用来测试
Aa=()=>{
alert(1);
}
render() {
return (
<div className='App'>
<Button onClick={this.fun} >点击</Button>
{
this.state.flag && <D visible={true} AA={this.Aa} />
}
</div>
)
}
}
export default App;
this.state.flag
为true
才会渲染D组件。D是子组件。
图片:
子组件:
import React, { Component } from 'react';
import { Modal, Button } from 'antd';
import 'antd/dist/antd.css';
// 组件名自己起,这里是D
class D extends Component {
constructor(props) {
super(props);
this.state = {
visible: this.props.visible //由父组件的props决定,this.props.xx
}
}
// 生命周期函数,接受传入的props,现在这个生命周期仍可以用。官网推荐使用新的生命周期static
// getDerivedStateFromProps,它的state永远取决于父组件的props,将在后续文章探索它的使用方法。
componentWillReceiveProps(nextProps){
this.setState({
visible: nextProps.visible
})
}
handleOk = e => {
this.setState({
visible: false,
}, () => console.log(' handleOk visible', this.state.visible));
this.props.AA(); //在子组件中调用父组件的AA方法
};
handleCancel = e => {
this.setState({
visible: false
}, () => {
console.log('handleCancel visible', this.state.visible)
});
};
render() {
console.log('render visible', this.state.visible)
return (
<div>
<Modal
visible={this.state.visible}
title={<span>请认真阅读</span>}
okText="确认"
cancelText="取消"
onOk={this.handleOk}
onCancel={this.handleCancel}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Modal>
</div>
);
}
}
export default D;
点击按钮后,渲染子组件,弹出对话框:
还有一种方法,在子组件内调用父组件的方法更新其state,也可达到效果。
父组件:
// 修改state,隐藏弹窗
Aa = () => {
this.setState({
visible: false
})
}
render内稍作修改:
{
this.state.flag && <D visible={true} onClick={this.Aa} />
}
子组件部分代码:
// 确认 执行逻辑处理后隐藏弹框
handleOk = e => {
.....
this.props.onClick(); //在子组件中调用父组件的AA方法
};
// 取消 隐藏弹框
cancelHandle = () => {
// 调用父组件的方法 改变state的visible为false,修改父组件的state才能重新渲染
this.props.onClick();
}