React 之 render props 的理解
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 的理解的更多相关文章
- React中render Props模式
React组件复用 React组件复用的方式有两种: 1.render Props模式 2.高阶组件HOC 上面说的这两种方式并不是新的APi. 而是利用Raect自身的编码特点,演化而来的固定编码写 ...
- React-代码复用(mixin.hoc.render props)
前言 最近在学习React的封装,虽然日常的开发中也有用到HOC或者Render Props,但从继承到组合,静态构建到动态渲染,都是似懂非懂,索性花时间系统性的整理,如有错误,请轻喷~~ 例子 以下 ...
- React高阶组件 和 Render Props
高阶组件 本质 本质是函数,将组件作为接收参数,返回一个新的组件.HOC本身不是React API,是一种基于React组合的特而形成的设计模式. 解决的问题(作用) 一句话概括:功能的复用,减少代码 ...
- 学习React系列(十)——Render Props
解决问题:将行为封装,供多个组件使用(在多个组件之间分享某段代码) 组件中的props属性中包含一个"render"属性(该属性为一个返回值为元素的方法),然后在该组件的rende ...
- React Render Props 模式
概述 Render Props模式是一种非常灵活复用性非常高的模式,它可以把特定行为或功能封装成一个组件,提供给其他组件使用让其他组件拥有这样的能力,接下来我们一步一步来看React组件中如何实现这样 ...
- 可复用 React 的 HOC 以及的 Render Props
重复是不可能的,这辈子都不可能写重复的代码 当然,这句话分分钟都要被产品(领导)打脸,真的最后一次改需求,我们烦恼于频繁修改的需求 虽然我们不能改变别人,但我们却可以尝试去做的更好,我们需要抽象,封装 ...
- [React] Use Prop Collections with Render Props
Sometimes you have common use cases that require common props to be applied to certain elements. You ...
- [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 ...
- react 高阶组件的 理解和应用
高阶组件是什么东西 简单的理解是:一个包装了另一个基础组件的组件.(相对高阶组件来说,我习惯把被包装的组件称为基础组件) 注意:这里说的是包装,可以理解成包裹和组装: 具体的是高阶组件的两种形式吧: ...
随机推荐
- List<E>
List<E>——列表 有序,存储和读取的顺序是一致的 由整数索引 允许重复 add(int index,E element)——将元素插入指定位置 get(int index)——获取指 ...
- 方法重载overload与方法重写overwrite
方法重载overload: 在同一个类中,出现相同的方法名,与返回值无关,参数列表不同:1参数的个数不同 2参数类型不同 在调用方法时,java虚拟机会通过参数列表来区分不同同名的方法 方法重写ove ...
- Linux_高级用法
LInux如何压缩和解压文件 文件压缩与解压主要讲zip和tar 安静模式和文件夹 zip -r -q -o test.zip 需要打包文件 查看打包文件 du -h test.zip 上节学过的fi ...
- LeetCode 112. 路径总和(Path Sum) 10
112. 路径总和 112. Path Sum 题目描述 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和. 说明: 叶子节点是指没有子节点的节 ...
- 循环(数组循环、获取json数据循环)、each()循环详解
return; // 退出循环(不满足,退出此次循环.下次满足条件,依然会走此循环)return false; //退出函数(退出所有) 一. 数组循环: html: <div class=&q ...
- Linux安装Python3流程
安装必要的依赖库文件 yum -y install zlib zlib-devel bzip2 bzip2-devel ncurses ncurses-devel readline readline- ...
- [Luogu5280][ZJOI2019]线段树(线段树+DP)
https://www.luogu.org/blog/Sooke/solution-p5280 首先想到对线段树上每个点分别维护有多少棵线段树在它上有标记(f[]),然后想到对于每个操作,根据转移的不 ...
- Aop 打印参数日志时,出现参数序列化异常。It is illegal to call this method if the current request is not in asynchron
错误信息: nested exception is java.lang.IllegalStateException: It is illegal to call this method if the ...
- 元素的colspan和rowspan
colspan和rowspan这两个属性用于创建特殊的表格. colspan用来指定单元格横向跨越的列数:colspan就是合并列的,colspan=2就是合并两列. rowspan用来指定单元格纵向 ...
- C# 用Redis实现的分布式锁
Redis实现分布式锁(悲观锁/乐观锁) 对锁的概念和应用场景在此就不阐述了,网上搜索有很多解释,只是我搜索到的使用C#利用Redis的SetNX命令实现的锁虽然能用,但是都不太适合我需要的场景. 基 ...