React中封装Modal组件为子组件并多次复用,父组件向子组件传递函数

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.flagtrue才会渲染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();
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清颖~

您的鼓励让我们一起进步,加油!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值