React Render Props解释

Render props is a relatively new and popular way to share/reuse code in React. React router and Downshift are libraries that use render props.

渲染道具是一种相对较新的流行方法,用于在React中共享/重用代码。 React routerDownshift是使用渲染道具的库。

What is a render prop? It is basically a prop with a function as its value. This function prop informs the component of what to render. From the React docs, a component with a render prop takes a function that returns a React element and calls it instead of implementing its own render logic.

什么是渲染道具? 它基本上是一个具有功能价值的道具。 此功能道具通知组件要渲染的内容。 从React文档中带有渲染道具的组件采用一个函数,该函数返回React元素并调用它,而不是实现自己的渲染逻辑

Now that we know what render props are let's see it in action.

现在我们知道了什么渲染道具,让我们来看看它的作用。

使用渲染道具重用代码 (Reuse code using render props)

Essentially, what we want to be able to do is share state/behavior of an existing component to other components that need the same state.

本质上,我们希望能够做的是将现有组件的状态/行为共享给需要相同状态的其他组件。

So for example, we have a simple app that tracks the mouse movement on a screen:

因此,例如,我们有一个简单的应用程序来跟踪鼠标在屏幕上的移动:

import React from 'react'
import ReactDOM from 'react-dom'

const App = React.createClass({
  state = { x: 0, y: 0 }

  handleMouseMove = (event) => {
    this.setState({
      x: event.clientX,
      y: event.clientY
    })
  },

  render() {
    const { x, y } = this.state

    // As the mouse moves around the scree, the component displays the x, y coordinates
    return (
      <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
        <h1>The mouse position is ({x}, {y})</h1>
      </div>
    )
  }
})

ReactDOM.render(<App/>, document.getElementById('app'))

If we wanted to share this behavior to another component, how would we use render props to wrap this behavior?

如果我们想与其他组件共享此行为,我们将如何使用render props来包装此行为?

import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'

class Mouse extends React.Component {
  static propTypes = {
    render: PropTypes.func.isRequired
  }

  state = { x: 0, y: 0 }

  handleMouseMove = (event) => {
    this.setState({
      x: event.clientX,
      y: event.clientY
    })
  }

  render() {
    return (
      <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
        {this.props.render(this.state)}
      </div>
    )
  }
}

class App extends React.Component {
  render() {
    return (
      <div style={{ height: '100%' }}>
        <Mouse render={({ x, y }) => (
          <h1>The mouse position is ({x}, {y})</h1>
        )}/>
      </div>
    )
  }
}

ReactDOM.render(<App/>, document.getElementById('app'))

What we've done is create a new component <Mouse> that takes a render prop whose value is a function. The prop is then used inside <Mouse>'s render to determine what to render.

我们要做的是创建一个新组件<Mouse> ,它使用一个render道具,其值为函数。 然后在<Mouse>的渲染中使用该道具来确定要渲染的内容。

Note: The <Mouse> state is exposed in <App> component using the render prop. This allows for component App to render whatever it wants with that state.

注意: <Mouse>状态使用渲染道具在<App>组件中公开。 这允许组件App在该状态下呈现所需的任何内容。

The render prop in <Mouse> allows it to dynamically determine what to render; therefore, it is totally portable and we can use it for many different use cases we might have with the mouse position.

<Mouse>的render prop允许它动态确定要渲染的内容。 因此,它是完全可移植的,我们可以将其用于鼠标位置可能具有的许多不同用例。

import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
import cat from "./cat.png";

class Mouse extends React.Component {
  static propTypes = {
    render: PropTypes.func.isRequired
  }

  state = { x: 0, y: 0 }

  handleMouseMove = (event) => {
    this.setState({
      x: event.clientX,
      y: event.clientY
    })
  }

  render() {
    console.log("mouse", this.state)
    return (
      <div onMouseMove={this.handleMouseMove}>
        {this.props.render(this.state)}
      </div>
    )
  }
}

class Cat extends React.Component {
  render() {
    const {x, y} = this.props.mouse;

    return (
      <img src={cat} style={{ position: 'absolute', left: x, top: y, height: 50 }} />
    );
  }
}

class App extends React.Component {
  render() {
    return (
      <div>
        <div>
          <Mouse render={({ x, y }) => (
            <h1>The mouse position is ({x}, {y})</h1>
          )}/>
        </div>

        // different use case for the mouse position
        <div>
          <Mouse render={({ x, y }) => (
            <Cat mouse={{ x, y }} />
          )}/>
        </div>
      </div>
    )
  }
}

export default App;

We just added a new component <Cat> which uses the mouse position behavior to move a cat around our screen!

我们刚刚添加了一个新组件<Cat> ,它使用鼠标的位置行为在屏幕上移动了一只猫!

Remember that we do not have to use a prop named render. As long as we use a prop whose value is a function, that the component uses to determine what to render, we are using the render prop pattern. This is to say, we can use the children prop:

请记住,我们不必使用名为render的道具。 只要我们使用其值为函数的道具(该组件用来确定要渲染的内容),我们就使用render prop模式。 也就是说,我们可以使用children道具:

<Mouse children={({ x, y }) => (
  <p>The mouse position is {x}, {y}</p>
)}/>

This is commonly known as the children as a function concept and it is the exact same thing as render prop. react-motion uses this concept.

这通常被称为children as a function概念,与render prop完全相同。 react-motion使用此概念。

结论 (Conclusion)

That is it! Render props makes reusing code really simple. Remember every time we create components we want them to be as reusable as possible. So make sure you explore more on how to make your components portable. This talk by Michael Jackson is very resourceful and he explains why render props is a better technique over using higher order components (HOCs).

这就对了! 渲染道具使重用代码变得非常简单。 记住,每次创建组件时,我们都希望它们尽可能地可重用。 因此,请确保您进一步探索如何使组件可移植。 迈克尔·杰克逊Michael Jackson )的演讲非常足智多谋,他解释了为什么render props比使用higher order components (HOCs)更好的技术。

Happy coding everyone!

祝大家编码愉快!

翻译自: https://scotch.io/tutorials/react-render-props-explained

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值