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

相关推荐
光影少年4 天前
RN 的EventEmitter 双向通信
前端·react native·react.js
光影少年5 天前
React Native Module 注册流程
前端·react native·react.js
光影少年8 天前
RN Bridge 原理
前端·react native·react.js
moMo8 天前
用 React 写一个 TodoList
react native·react.js
光影少年9 天前
RN原生交互 & 桥接
前端·javascript·react native·react.js·前端框架
光影少年11 天前
RN 路由栈管理、页面销毁、返回拦截
javascript·react native·react.js
光影少年12 天前
react navite 页面跳转、传参、路由监听、导航栏自定义
前端·react native·react.js
光影少年13 天前
React Navigation 核心使用(Stack/Tab/Drawer)
前端·javascript·react native·react.js·前端框架