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>
    );
  }
}

  

233

原文地址:https://www.cnblogs.com/lemos/p/11006959.html

时间: 2024-08-30 13:23:53

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

React hooks能替代Redux,HOC和render props么?

最近开始学习React,记录一下心得. React hooks是16.8.0推出的,其目的是为了替换class,HOC,render props.同时网传hooks也将终结redux,那么本文将讨论hooks究竟能不能替换掉redux,HOC,render props. 1. Hooks替代Redux. 与其说Hooks替代Redux,不如说是Context在替代Redux.Context是16.3.0推出的(之前也有,但是API不一样且基本没人用).其实从Context开始,可以说不用redu

深入浅出 React 的 HOC 以及的 Render Props

重复是不可能的,这辈子都不可能写重复的代码 当然,这句话分分钟都要被产品打脸,天天喊着改需求,老哥,这里改下可好? 所以,我们需要抽象,封装重复的功能或者逻辑,这样改需求,也不用到处改 那么这次我们来讲讲 React 里的高级组件 React 高级组件有两种方式: 使用高阶组件( Higher Order Component ==> HOC ) 子组件作为函数的模式( Render Props ) 高阶组件 首先来说说高阶组件,它不是 React 的提供的 API,它是模式,一种增强组件的模式,

[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 same example and simple refactoring the Togglecomponent which handles the render prop. const ToggleStream = componentFromStream(props$ => { const { h

react高阶组件的理解

[高阶组件和函数式编程] function hello() { console.log('hello jason'); } function WrapperHello(fn) { return function() { console.log('before say hello'); fn(); console.log('after say hello'); } } // hello 这时候等于 WrapperHello函数中返回的 匿名函数 // 在设计模式中这种操作叫做 装饰器模式 // 高

Node.js 之react.js组件-Props应用

render props是指一种在 React 组件之间使用一个值为函数的 prop 共享代码(个人理解:将组件进行函数化,通过调用组件名实现,组件的利用,以元素的形式调用,并渲染画面) 具有 render prop 的组件接受一个函数,该函数返回一个 React 元素并调用它而不是实现自己的渲染逻辑. 具体实例(代码来自官网):URL:https://zh-hans.reactjs.org/docs/render-props.html#___gatsby 笔记:代码中实现的组件调用,是将一个组

React入门---属性(props)-8

Props 和 State对于组件Component是非常重要的两个属性. 区别:State对于模块来说是 自身属性:   Props对于模块来说是 外来属性: 同样的,props也是只作用于当前的组件,绝不影响其他组件: 给组件 <ComponentFooter> 添加props属性和属性值: 例:从父组件index.js给子组件footer.js传送数据: class Index extends React.Component{ render(){ return( //里面分别是 头部 主

Webpack + React 开发 03 props

React中组件的用法与原生的 HTML 标签完全一致,可以任意加入属性,比如 <HelloWorld name="John"> ,就是 HelloWorld 组件加入一个 name 属性,值为 John.和直接使用 <div name="John"> 不同,React组件被渲染出来之后,在渲染之后的dom节点中是不能直接看得到 name 属性的,怎么获取呢?组件的属性可以在组件类的 this.props 对象上获取,比如 name 属性就可

A Bite Of React(2) Component, Props and State

component component:用户自己定义的元素 const element = <Welcome name="Sara" />; class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } } 遇到自己定义的component Welcom,React会将它的属性(name)作为对象传递给组建Welcom,即{

React -- 组件封装&amp;props

一.组件封装 一个函数就是一个组件,该函数接受一个props对象,并返回一个React元素 function Welcome(props) { return <h1>Hello, {props.name}</h1>; } 通过class和React.Component也可以定义一个组件,跟上面的组件是等价的 class Welcome extends React.Component { render() { return <h1>Hello, {this.props.n