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 来更简洁地实现。

相关推荐
全栈前端老曹18 小时前
【ReactNative】核心组件与 JSX 语法
前端·javascript·react native·react.js·跨平台·jsx·移动端开发
光影少年20 小时前
RN vs Flutter vs Expo 选型
前端·flutter·react native
Swift社区2 天前
RN 项目中“页面存在 ≠ 页面可见”会导致哪些隐藏 Bug?
react native·bug·react
赵财猫._.3 天前
React Native鸿蒙开发实战(十):鸿蒙NEXT深度适配与未来展望
react native·react.js·harmonyos
2401_860319523 天前
在React Native鸿蒙跨平台开发采用分类网格布局,通过paramRow和paramLabel/paramValue的组合展示关键配置信息
react native·react.js·harmonyos
2301_796512523 天前
使用如Redux、MobX或React Context等状态管理库来管理状态,React Native鸿蒙跨平台开发来实战
react native·react.js·harmonyos
洞窝技术3 天前
自建 React Native 热修复,让线上事故 30 秒“归零”
react native
2401_860494703 天前
在React Native中实现鸿蒙跨平台开发中开发一个运动类型管理系统,使用React Navigation设置应用的导航结构,创建一个堆栈导航器
react native·react.js·harmonyos
2301_796512523 天前
使用状态管理、持久化存储或者利用现有的库来辅助React Native鸿蒙跨平台开发开发一个允许用户撤销删除的操作
javascript·react native·react.js
2301_796512523 天前
React Native鸿蒙跨平台开发包含输入收入金额、选择收入类别、记录备注和日期等功能,实战react-native-paper组件
javascript·react native·react.js