1.基本概念

在调用组件时,引入一个函数类型的 prop,这个 prop定义了组件的渲染方式。

2.回调渲染

回顾组件通信的几种方式

父-> 子 props

子-> 父 回调、消息通道

任意 状态提升、Context、Redux 等

而 render props 本质实际上是使用到了回调的方式来通信。只不过在传统的 js 回调是在构造函数中进行初始化(使用回调函数作为参数),而在 react 中,现在可以通过 props 传入该回调函数,就是我们所介绍的 render prop。

从结果论来说,回调的目的是渲染子组件,而渲染的外部细节需要通过父组件注入,实现了控制反转。

从目的论来说,我们的目的是组件复用。它实现 了内部细节封装,并将外部细节(通过回调函数的形式 )暴露,达到了灵活复用的目的。

3.著名应用实例:

React Router 、 Downshift 和 react-motion

4.举例说明

示例1:

依赖 props.children 渲染组件,把控制权交给上层组件,子 组件实现控制反转。

子组件

import React, { Component } from "react";

export class ScrollPos extends Component {
state = {
position: null
}; componentDidMount() {
window.addEventListener("scroll", this.handleScroll);
} componentWillUnmount() {
window.removeEventListener("scroll", this.handleScroll);
} handleScroll = e => {
const scrollTop = e.target.scrollingElement.scrollTop;
this.setState((state, props) => {
return { position: scrollTop };
});
}; render() {
return <div className='scroll'>{this.props.children(this.state.position)}</div>;
}
} export default ScrollPos;

父组件

import React from "react";
import "./App.css";
import ScrollPos from "./component/ScrollPos"; function App() {
return (
<div className="App">
<ScrollPos>
{position => <h1>{"Awesome !".substr(0, position * 15)}</h1>}
</ScrollPos>
<div className="spacer" />
</div>
);
} export default App;

示例2:

使用 props 传回调函数,需要多少回调就需要设置多少个 prop,比如这里 Auth 子组件既需要登录成功回调又需要登录失败回调。

子组件

const Auth= (props) => {
const userName = getUserName(); if (userName) {
const allProps = {userName, ...props};
return (
<React.Fragment>
{props.login(allProps)}
</React.Fragment>
);
} else {
<React.Fragment>
{props.nologin(props)}
</React.Fragment>
}
};

父组件

<Auth
login={({userName}) => <h1>Hello {userName}</h1>}
nologin={() => <h1>Please login</h1>}
/>

5.浅比较性能优化

如果在父组件中传递 props时 使用箭头函数,每次都会生成新的函数,造成传递给子组件的 props 每次都是新的,引起子组件重新渲染(子组件继承 PureComponent 无效)。因此考虑不使用箭头函数转为使用实例属性的方式:

class MouseTracker extends React.Component {
// 定义为实例方法,`this.renderTheCat`始终
// 当我们在渲染中使用它时,它指的是相同的函数
renderTheCat(mouse) {
return <Cat mouse={mouse} />;
} render() {
return (
<div>
<h1>Move the mouse around!</h1>
<Mouse render={this.renderTheCat} />
</div>
);
}
}

*  注:这里也可以直接将 renderTheCat 这个渲染方法变成组件。类似于 下面代码中的 movies

import Movies from "./components/movies";

<Route path="/movies" component={Movies}/>

注:回调的理解

React 之 render props 的理解的更多相关文章

  1. React中render Props模式

    React组件复用 React组件复用的方式有两种: 1.render Props模式 2.高阶组件HOC 上面说的这两种方式并不是新的APi. 而是利用Raect自身的编码特点,演化而来的固定编码写 ...

  2. React-代码复用(mixin.hoc.render props)

    前言 最近在学习React的封装,虽然日常的开发中也有用到HOC或者Render Props,但从继承到组合,静态构建到动态渲染,都是似懂非懂,索性花时间系统性的整理,如有错误,请轻喷~~ 例子 以下 ...

  3. React高阶组件 和 Render Props

    高阶组件 本质 本质是函数,将组件作为接收参数,返回一个新的组件.HOC本身不是React API,是一种基于React组合的特而形成的设计模式. 解决的问题(作用) 一句话概括:功能的复用,减少代码 ...

  4. 学习React系列(十)——Render Props

    解决问题:将行为封装,供多个组件使用(在多个组件之间分享某段代码) 组件中的props属性中包含一个"render"属性(该属性为一个返回值为元素的方法),然后在该组件的rende ...

  5. React Render Props 模式

    概述 Render Props模式是一种非常灵活复用性非常高的模式,它可以把特定行为或功能封装成一个组件,提供给其他组件使用让其他组件拥有这样的能力,接下来我们一步一步来看React组件中如何实现这样 ...

  6. 可复用 React 的 HOC 以及的 Render Props

    重复是不可能的,这辈子都不可能写重复的代码 当然,这句话分分钟都要被产品(领导)打脸,真的最后一次改需求,我们烦恼于频繁修改的需求 虽然我们不能改变别人,但我们却可以尝试去做的更好,我们需要抽象,封装 ...

  7. [React] Use Prop Collections with Render Props

    Sometimes you have common use cases that require common props to be applied to certain elements. You ...

  8. [Recompose] Refactor React Render Props to Streaming Props with RxJS and Recompose

    This lesson takes the concept of render props and migrates it over to streaming props by keeping the ...

  9. react 高阶组件的 理解和应用

    高阶组件是什么东西 简单的理解是:一个包装了另一个基础组件的组件.(相对高阶组件来说,我习惯把被包装的组件称为基础组件) 注意:这里说的是包装,可以理解成包裹和组装: 具体的是高阶组件的两种形式吧: ...

随机推荐

  1. asp.net编程基础

    vs常用两个快捷键:打开即时窗口 ctrl+alt+i : 快速代码格式排版:ctrl+k+d 一:Page:页面 Page.IsPostBack  判断页面是否第一次加载用 if(Page.IsPo ...

  2. eNSP基于接口地址池的dhcp服务

    拓扑图如下 基于接口的dhcp是最简单的一种 我们对路由器的两个端口分别设置ip地址为192.168.1.254 192.168.2.254 然后分别进入接口进行下一步配置 dhcp select i ...

  3. [转帖]MySQL语句大全

    MySQL语句大全 https://www.cnblogs.com/jicki/p/5548676.html 一.连接mysql. 格式: mysql -h主机地址 -u用户名 -p用户密码 二.修改 ...

  4. [Oracle] - 使用32位 PLSQL(PL/SQL Developer)登陆64位Oracle失败之解决

    配置环境 Oracle服务端oracle_winx64_12c_database.iso Oracle客户端instantclient-basiclite-nt-12.1.0.1.0.zip 集成开发 ...

  5. [DevExpress] - 在 DataGrid 中添加多选复选框的方法

    设置方法 在 GridView 中设置 OptionSelection 属性如下: 效果 参考资料 https://stackoverflow.com/a/9078848http://blog.csd ...

  6. cesium 水面、淹没 效果

    水面效果 参考: http://cesiumcn.org/topic/158.html http://api.rivermap.cn/cesium/rivermap/map.html https:// ...

  7. Python类和实例调用

    self指向的是实例对象,作为第一个参数,使用时不需要传入此参数. class Student(object): #定义一个Student类, def __init__(self, name, sco ...

  8. Python02之continue,break语句

    Python中的break和continue用法基本一样 break和continue都是用在while和for循环中,而不是跳出if...elif..else的判断语句中,跳出是直接跳出语句所在的w ...

  9. C++11<functional>深度剖析:背景、原理、接口与实现

    自C++11以来,C++标准每3年修订一次.C++14/17都可以说是更完整的C++11:即将到来的C++20也已经特性完整了. C++11已经有好几年了,它的年龄比我接触C++的时间要长10倍不止吧 ...

  10. matplotlib实例笔记

    下面的图型是在一幅画布上建立的四个球员相关数据的极坐标图 关于这个图的代码如下: #_*_coding:utf-8_*_ import numpy as np import matplotlib.py ...