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-11-10 03:15:30