React - children props与render props

React - children props与render props

在 React 中,当需要向组件内部动态传入带内容的结构时,有两种常用方案:children props 和 render props。

1. children props 方式

children props是通过组件标签体来传入结构,这是最简单直接的方式。

局限性:如果传入的子组件(如 B 组件)需要使用父组件(A 组件)内部的数据,这种方式就无法实现了。

js 复制代码
// 父组件使用方式 
<A> <B>这是要传入A组件的内容</B> </A> 
// A组件内部获取方式
class A extends React.Component { 
  render() { 
      return ( 
        <div>
           {/* 直接渲染传入的内容 */} 
           {this.props.children} 
        </div> 
    ); 
  }
 }

2. render props 方式

render props 是通过组件的属性传入一个函数 ,这个函数返回要渲染的结构,并且可以携带父组件的数据

kotlin 复制代码
<A render={(data) => <C data={data}></C>}></A>
A组件: {this.props.render(内部state数据)}
C组件: 读取A组件传入的数据显示 {this.props.data} 
jsx 复制代码
import { Component  } from "react";
import "./index.css";
export default class A extends Component{
    state = {
        verse:'露从今夜白'
    }
    render(){
        console.log('render-父亲')
        return(
            <div className='Father'>
                <h1>我是Father</h1>
                <B><C/></B>
                <B render={(name)=><D name={name}/>} />
            </div>
        )
    }
}
class B extends Component{
    state = {name:'我的未来式'}
    render(){
        console.log('render-B',this.props)
       let {name} = this.state
        return(
            <div className='Son' >
                <h1>我是B</h1>
                {this.props.children}
                {/* 只有当render存在时才调用,渲染第一个时,无该方法 */}
                {this.props.render && this.props.render(name)}
            </div>
        )
    }
}
class C extends Component{
    render(){
        console.log('render-孙子')
        // let { name } = this.props
        return(
            <div className='grandson' >
                <h1>我是C</h1>
                <p>第一种方法渲染</p>
            </div>
        )
    }
}
class D extends Component{
    render(){
        let { name } = this.props
        console.log('render-孙子',name)
        return(
            <div className='grand' >
                <h1>我是D</h1>
                <p>获取第二种方法的name,name为:{name}</p>
            </div>
        )
    }
}

总结:两种方式的对比

  1. children props

    • 适用于简单场景,只是单纯传入要渲染的内容
    • 使用方式:通过组件标签体传入
    • 局限性:无法将父组件内部数据传递给子组件
  2. render props

    • 适用于需要共享组件内部状态和方法的场景
    • 使用方式:通过组件属性传入一个返回 JSX 的函数
    • 优势:可以将组件内部的数据和方法传递给子组件,实现组件间的数据共享
    • 灵活性高,可以根据需要渲染不同的子组件结构

示例:

jsx 复制代码
import React from 'react';

// 1. children props 示例
class ChildrenExample extends React.Component {
  render() {
    return (
      <div className="border p-4 m-2">
        <h3>Children Props 示例</h3>
        {/* 直接渲染通过标签体传入的内容 */}
        {this.props.children}
      </div>
    );
  }
}

// 2. Render props 示例 - 提供数据的组件
class DataProvider extends React.Component {
  state = {
    user: {
      name: "张三",
      age: 25,
      hobbies: ["篮球", "读书", "旅行"]
    },
    theme: "light"
  };
  
  // 切换主题的方法
  toggleTheme = () => {
    this.setState(prevState => ({
      theme: prevState.theme === "light" ? "dark" : "light"
    }));
  };
  
  render() {
    // 将内部状态和方法通过render函数传递出去
    return this.props.render({
      ...this.state,
      toggleTheme: this.toggleTheme
    });
  }
}

// 使用数据的组件1
class UserInfo extends React.Component {
  render() {
    const { user } = this.props;
    return (
      <div className="p-3">
        <h4>用户信息</h4>
        <p>姓名:{user.name}</p>
        <p>年龄:{user.age}</p>
        <p>爱好:{user.hobbies.join("、")}</p>
      </div>
    );
  }
}

// 使用数据的组件2
class ThemeSwitcher extends React.Component {
  render() {
    const { theme, toggleTheme } = this.props;
    return (
      <div className="p-3">
        <h4>主题切换</h4>
        <p>当前主题:{theme}</p>
        <button onClick={toggleTheme} className="btn btn-primary">
          切换主题
        </button>
      </div>
    );
  }
}

// 主应用组件
class App extends React.Component {
  render() {
    return (
      <div className="container mt-4">
        <h2>React 动态传入内容示例</h2>
        
        {/* Children Props 使用 */}
        <ChildrenExample>
          <p>这是通过children props传入的内容</p>
          <button className="btn btn-success">这是一个按钮</button>
        </ChildrenExample>
        
        {/* Render Props 使用 */}
        <div className="border p-4 m-2">
          <h3>Render Props 示例</h3>
          <DataProvider render={(data) => (
            <div className="d-flex gap-4">
              <UserInfo user={data.user} />
              <ThemeSwitcher theme={data.theme} toggleTheme={data.toggleTheme} />
            </div>
          )} />
        </div>
      </div>
    );
  }
}

export default App;

在实际开发中,根据是否需要共享数据来选择合适的方式。如果需要组件间的数据共享,render props 是更好的选择。另外,随着 React Hooks 的普及,一些原本需要用 render props 解决的问题,现在也可以通过自定义 Hooks 来更简洁地实现。

相关推荐
空中海1 小时前
02 React Native状态、导航、数据流与设备能力
javascript·react native·react.js
空中海2 小时前
04 React Native工程化、质量、发布与生态选型
javascript·react native·react.js
sealaugh325 小时前
react native(学习笔记第三课) 英语打卡微应用(2)-从上传图片开始
笔记·学习·react native
空中海6 小时前
05 React Native架构设计、主线项目与专家实践
javascript·react native·react.js
一个扣子2 天前
降低 Android APK 体积:Hermes 的字节码格式与资源压缩
react native·字节码·构建优化·包体积优化·android性能·hermes·apk瘦身
cn_mengbei3 天前
用React Native开发OpenHarmony应用:Reanimated共享元素过渡
javascript·react native·react.js
祖国的好青年5 天前
VS Code 搭建 React Native 开发环境(Windows 实战指南)
android·windows·react native·react.js
一个扣子5 天前
性能面板解读:通过 Hermes Runtime 测量函数执行耗时
react native·chrome devtools·hermes·性能面板·函数耗时·performance api
一个扣子7 天前
Hermes 的 Android 与 iOS 平台差异化配置详解
react native·字节码·新架构·hermes·android配置·ios配置·平台差异
茅盾体7 天前
React Native
android·react native·react.js