• 九、React中的组件、父子组件、React props父组件给子组件传值、子组件给父组件传值、父组件中通过refs获取子组件属性和方法


    一、概述

    • React中的组件: 解决html 标签构建应用的不足。
    • 使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入。
    • 【父子组件】:组件的相互调用中,我们把调用者称为父组件,被调用者称为子组件

    二、父子组件传值

    父组件给子组件传值方法分为2步:

    1、父:在调用子组件的时候定义一个属性:

    <Header msg='首页'></Header>
    

    2、 子:子组件里面调用:

    this.props.msg
    

    【说明】父组件还可以把整个父组件传给子组件(此处存疑,新版本可能已失效)
    【父】:

    <Header home={this}></Header>
    

    【子】:

    this.props.home; //获取整个父组件
    this.props.home.state.msg; //获取父组件其中的state数据
    this.props.home.run; //获取父组件中函数
    

    1.父组件向子组件传【值】示例--------:

    0.【App.js】根组件:

    import React from 'react';
    import './App.css';
    import Home from './components/Home.js'; //1.引入首页、新闻组件
    import News from './components/news.js';
    
    function App() {
      return (
        <div className="App">  
        {/* 2.调用首页、新闻、组件*/}
            <Home />
            <hr/>
            <News />
        </div>
      );
    }
    export default App;
    

    1.父1【./components/Home.js】首页组件:

    import React, { Component } from 'react';
    import Header from './Header.js'; //0.引入 公共头组件
    
    class Home extends Component {
        constructor(props){
            super(props);   
            this.state={
              title:'首页组件' //1.头部名字
            }
        }
     
        render() {
          return (
            <div>
            <Header title={this.state.title} /> {/*2.用title传此页面的名字到header.js子组件*/}
            </div>
          );
        }
      }
      export default Home;
    

    3.父2【./components/News.js】新闻组件:

    import React, { Component } from 'react';
    import Header from './Header.js'; //0.引入 公共头组件
    
    class News extends Component {
        constructor(props){
            super(props);   
            this.state={
              title:'新闻组件' //1.头部名字
            }
        }
     
        render() {
          return (
            <div>
            <Header title={this.state.title} /> {/*2.用title传此页面的名字到header.js子组件*/}
            </div>
          );
        }
      }
      export default News;
    

    3.子【./components/Header.js】公共头组件:

    import React, { Component } from 'react';
    
    class Header extends Component {
        constructor(props){
            super(props);
            
            this.state={
              title:'头部组件' 
            }
        }
        
        render() {
          return (
            <div>
            <h1>{this.props.title}</h1> {/*2.接收来自父组件传来的title*/}
            </div>
          );
        }
      }
      export default Header;
    

    效果:在根组件引入首页、新闻组件效果:

    • 首页组件:引用头部组件,并向其传入title:首页组件
    • 新闻组件:引用头部组件,并向其传入title:新闻组件
    • 达到:用同一个 头部组件,显示自己的头部的目的;
      在这里插入图片描述

    2.父组件向子组件传【方法】示例----------:

    【Home.js】:

    import React, { Component } from 'react';
    import Header from './Header.js';
    
    class Home extends Component {
        constructor(props){
            super(props);   
            this.state={
              title:'首页组件'
            }
        }
    
        //1.准备向子组件header传的方法
        hello=()=>{
          alert('这是首页组件的hello方法!')
        }
     
        render() {
          return (
            <div>
              {/*2.把父组件的方法传到子组件前,要先在此处写 hi={this.hello} */}
            <Header title={this.state.title} hi={this.hello} />
            </div>
          );
        }
      }
      export default Home;
    

    【Header.js】:
    注意:此传的Home父组件的方法,只能在此Home父组件,内使用;在如新闻组件内,执行此方法则无效

    import React, { Component } from 'react';
    
    class Header extends Component {
        constructor(props){
            super(props);
            
            this.state={
              title:'头部组件'
            }
        }
        
        render() {
          return (
            <div>
            <h1>{this.props.title}</h1>
            {/* 1.在子组件内执行父组件传过来的方法;
             2.此处的this.props.xxx 取决于父组件的xxx名,xxx={this.ff} */}
            <button onClick={this.props.hi}>执行首页组件传过来的hello方法</button>
            </div>
          );
        }
      }
      export default Header;
    

    效果:
    在这里插入图片描述

    3.传递整个父组件到子组件【此方法在最新版本无法正确引用可能已取消】

    Home.js【方法存疑】

    //1.准备向子组件header传的方法
        hello=()=>{
          alert('这是首页组件的hello方法!')
        }
    <Header home={this} />
    

    Header.js【方法存疑】

    <button onClick={this.props.home.hello}>执行首页组件内的方法hello</button>
    

    报错:

    TypeError: Cannot read property 'hello' of undefined
    Header.render
    C:/Users/Administrator/Desktop/react/my-app/src/components/Header.js:17
      14 |  <div>
      15 |  <h1>{this.props.title}</h1>
      16 |  {/* 1.在子组件内执行父组件任何部分数据、方法 */}
    > 17 |  <button onClick={this.props.home.hello}>执行首页组件内的方法hello</button>
         | ^  18 | 
      19 |  
      20 |  </div>
    View compiled
    

    4.子组件(header.js)调用父组件(home.js)的state数据

    父【home.js】

    import React, { Component } from 'react';
    import Header from './Header.js';
    
    class Home extends Component {
        constructor(props){
            super(props);   
            this.state={
              title:'首页组件',
              msg:'首页的消息!'
            }
        }
    
        render() {
          return (
            <div>
              {/*3.把父组件state.msg数据,传给子组件(header.js) */}
            <Header home={this.state.msg} />
            <h2>这是首页组件的内容</h2>
            </div>
          );
        }
      }
      export default Home;
    

    子【header.js】

    import React, { Component } from 'react';
    
    class Header extends Component {
        constructor(props){
            super(props);       
            this.state={
              title:'头部组件'
            }
        }
        
        render() {
          return (
            <div>
            <h1>{this.props.title}</h1>
            {/* 1.在子组件内执行父组件的state.msg。(来自home={this.state.msg}) */}
            {this.props.home}
             
            </div>
          );
        }
      }
      export default Header;
    

    5.子组件调用父组件的函数,且向其传递消息 (此方法已失效)

    home.js

    import React, { Component } from 'react';
    import Header from './Header.js';
    
    class Home extends Component {
        constructor(props){
            super(props);   
            this.state={
              title:'首页组件',
              msg:'首页的消息!'
            }
        }
    
        //1.准备向子组件header传的方法,child_msg为接收来自子组件的消息
        hello=(child_msg)=>{
          alert('这是首页组件的hello方法!'+child_msg)
        }
     
        render() {
          return (
            <div>
              {/*3.把父组件[方法hello]传给子组件 [ he={this.hello} ] */}
            <Header title={this.state.title} hello={this.hello} />
            <h2>这是首页组件的内容</h2>
            </div>
          );
        }
      }
      export default Home;
    

    header.js

    import React, { Component } from 'react';
    
    class Header extends Component {
        constructor(props){
            super(props);
            
            this.state={
              title:'头部组件'
            }
        }
        
        render() {
          return (
            <div>
            <h1>{this.props.title}</h1>
            {/* 
            功能:子组件调用父组件的hello函数,并向其传自己的消息
            1.在子组件内[向]父组件传数据[.bind(this,'消息')];
            2.父组件对应的函数要有能接收参数
            */}
            <button onClick={this.props.hello.bind(this,'子组件的消息')}></button>
             
            </div>
          );
        }
      }
      export default Header;
    

    【父子组件传值的应用场景】

    1. 首先写了一个公共组件:【头部组件】,其它组件都会用到头部这个组件,但会稍有不同;
    2. 在【首页组件】调用 【头部组件】时,想要它显示成【首页头部组件】
    3. 在【新闻组件】调用 【头部组件】时,想要它显示成【新闻头部组件】

    此时,就可用父组件向子组件传值来解决这个问题,让【头组件】在对应页面显示【xxx头部组件】...
    在这里插入图片描述

    三、父组件主动获取子组件的state数据、函数

    1. 调用子组件的时候指定ref的值
    <Header ref='header'></Header>
    
    1. 通过this.refs.header 获取整个子组件实例
    this.refs.header
    

    1.实例:从父组件调用子组件的state数据

    Home.js

    import React, { Component } from 'react';
    import Header from './Header.js';
    import Footer from './footer.js'
    
    class Home extends Component {
        constructor(props){
            super(props);   
            this.state={
              title:'首页组件',
              msg:'首页的消息!'
            }
        }
    
        //2.函数:获取底部组件的state.msg数据
        getfooter=()=>{
          alert(this.refs.foo.state.msg);
        }
     
        render() {
          return (
            <div>
              
            <Header title={this.state.title} hello={this.hello} />
            <h2>这是首页组件的内容</h2>
    
            <hr/>
            {/*1.获取底部子组件的内部函数、state消息需先在底组件上定义 ref='foo' */}
            <Footer ref='foo' />
            {/*3.执行自写函数 调用子组件的state.msg*/}
            <button onClick={this.getfooter}>获取底组件的state.msg</button>
            <br/>
            
            </div>
          );
        }
      }
      export default Home;
    

    footer.js

    import React, { Component } from 'react';
    
    class Footer extends Component {
        constructor(props){
            super(props);
            
            this.state={
              title:'底部组件',
              msg:'来自底部组件的state.msg消息'
            }
        }
    
        footer_run=()=>{
          alert('底部组件函数消息!')
        }
        
        render() {
          return (
            <div>
            <h3>这是一个底部组件</h3>
                
            </div>
          );
        }
      }
      export default Footer;
    

    app.js

    import React from 'react';
    import './App.css';
    import Home from './components/Home.js';
    import News from './components/news.js';
    
    function App() {
      return (
        <div className="App">  
            <Home />
            <hr/>
            
        </div>
      );
    }
    export default App;
    

    结果
    在这里插入图片描述

    2.实例:从父组件调用子组件的方法

    【home.js】

    import React, { Component } from 'react';
    import Header from './Header.js';
    import Footer from './footer.js'
    
    class Home extends Component {
        constructor(props){
            super(props);   
            this.state={
              title:'首页组件',
              msg:'首页的消息!'
            }
        }
    
        //2.函数:获取底部组件的state.msg数据
        getfooter=()=>{
          this.refs.foo.footer_run();
        }
     
        render() {
          return (
            <div>
              
            <Header title={this.state.title} hello={this.hello} />
            <h2>这是首页组件的内容</h2>
    
            <hr/>
            {/*1.获取底部子组件的内部函数、state消息需先在底组件上定义 ref='foo' */}
            <Footer ref='foo' />
            {/*3.执行自写函数 调用子组件的footer_run()函数*/}
            <button onClick={this.getfooter}>获取底组件的footer_run()函数</button>
            <br/>
            
            </div>
          );
        }
      }
      export default Home;
    

    【footer.js】

    import React, { Component } from 'react';
    
    class Footer extends Component {
        constructor(props){
            super(props);
            
            this.state={
              title:'底部组件',
              msg:'来自底部组件的state.msg消息'
            }
        }
    
        footer_run=()=>{
          alert('底部组件footer_run函数的消息!')
        }
        
        render() {
          return (
            <div>
            <h3>这是一个底部组件</h3>
                
            </div>
          );
        }
      }
      export default Footer;
    

    【app.js】

    import React from 'react';
    import './App.css';
    import Home from './components/Home.js';
    import News from './components/news.js';
    
    function App() {
      return (
        <div className="App">  
            <Home />
            <hr/>    
        </div>
      );
    }
    export default App;
    

    结果:
    在这里插入图片描述

  • 相关阅读:
    sqlalchemy 基本操作
    Codeforces 716A Crazy Computer
    Codeforces 719B Anatoly and Cockroaches
    POJ 1067 取石子游戏
    P1028 数的计算
    P1914 一串字母
    P1308 统计单词数
    P1200 你的飞碟在这儿
    P1055 书号
    P1567 气温统计
  • 原文地址:https://www.cnblogs.com/chenxi188/p/11857803.html
Copyright © 2020-2023  润新知