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

相关推荐
真夜7 小时前
关于rn下载gradle依赖速度慢的问题
react native·gradle·android studio
十步杀一人_千里不留行1 天前
I Built an Offline-Capable App by Myself: React Native Frontend, C# Backend
前端·react native·typescript
烈焰晴天1 天前
一款基于 ReactNative 最新发布的`Android/iOS` 新架构文档预览开源库
android·react native·ios
米开朗积德1 天前
React Native原生Android SSL双向认证
react native
litongde2 天前
React Native 编程
react native·harmonyos
张元清7 天前
从零开始编写 useWindowSize Hook
react native·react.js
_一两风9 天前
React性能优化深度指南:从基础到高级技巧
react native·性能优化
谢尔登11 天前
【React Native】路由跳转
javascript·react native·react.js
Carson带你学Android12 天前
都2025了,【跨平台框架】到底该怎么选?
android·flutter·react native