React 之 render props 的理解

Posted lemos

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

以上是关于React 之 render props 的理解的主要内容,如果未能解决你的问题,请参考以下文章

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

[react] 请说说你对react的render方法的理解

react学习笔记1之声明组件的两种方式

React开发(118):报错处理

React丨props,state 和 render

React学习第六步:生命周期&render props模式&高阶组件&原理揭秘