zoukankan      html  css  js  c++  java
  • 九、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;
    

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

  • 相关阅读:
    高级特性(4)- 数据库编程
    UVA Jin Ge Jin Qu hao 12563
    UVA 116 Unidirectional TSP
    HDU 2224 The shortest path
    poj 2677 Tour
    【算法学习】双调欧几里得旅行商问题(动态规划)
    南洋理工大学 ACM 在线评测系统 矩形嵌套
    UVA The Tower of Babylon
    uva A Spy in the Metro(洛谷 P2583 地铁间谍)
    洛谷 P1095 守望者的逃离
  • 原文地址:https://www.cnblogs.com/chenxi188/p/11857803.html
Copyright © 2011-2022 走看看