回想一下,我们在react中,父组件给子组件传递某些东西(值、组件)的时候,是不是可以使用 props
和 children
这2个来帮助我们。
概念
props通常是我们定义在标签身上的东西,我们一般称之为标签属性, 例如下面
<div title="这是标签属性,也是props"></div> |
而children则是值react中的 props.children
,这个东西的作用是,存放标签体的内容,如何来理解呢?看下面
<!-- Parent是我们随便定义的一个组件 --> |
由此我们知道,只要它只一个组件,组件的开始标签和结束标签之间的东西,就是这个组件的标签体内容。
就以上面的这个例子,我们的Parent组件如何获取标签体的内容呢,自然是借助 props.children
了
function Parent(props) { |
区别
- props
通过往标签身上添加各种属性,以达到将某个值传递给子组件的方式
- children
通过往标签体内添加 结构 ,以达到将某个 HTML 结构传递给子组件的方式
由此我们也看出来了,props可以传递普通值,函数,HTML结构等等,而children只能传递HTML结构
思考
这里我们引申出一个问题,看下面的代码
function Parent() { |
上面我们定义了三个组件, 分别是父组件 Parent 、子组件 Child、孙组件 Grandson,我们的子组件里定义了一个变量 name
现在提一个需求,假如我想把子组件的name属性传递给孙组件,那么我应该怎么传?
聪明的人大概已经想到了,使用 props 传值
function Child() { |
到这里,大家可能心里会想,这不挺简单的吗?
是吗?那我们来对代码结构进行一个改造
function Parent() { |
看上面的代码,我还是那个需求,将子组件的name传递给孙组件,这个时候你该怎么传?
在这个代码结构中,子组件没办法使用 props 进行传值
仔细思考几分钟,想到解决方案了吗?
renderProps
为了解决上面提到的问题,我们可以借助 render props,让我们来对代码进行一个改造
function Parent() { |
这样,问题就解决了~
解释
- 什么是 render props
props就是写在标签身上的某个属性,属性值可以是普通值,也可以是函数,如果是函数,且这个函数的返回值是一个组件,我们就可以称之为是 render props
。
也就是说,你传递了一个函数,这个函数返回一个组件,然后你在子组件里调用了这个函数,让它返回的组件渲染到了页面上,那么这个函数就是一个渲染属性(render props)。
更直白的解释:你的这个props起到了渲染一个组件的作用。
<Child render={}>
这里的 render 属性是固定名字吗
它不是一个固定名字,你可以是render,也可以是其他任意的名字,例如我下面的 fn
<Child fn={(name) => <Grandson name={name}/>} /> |
<Parent> <Child/> </Parent>
是不是可以理解为 Vue里Solt的写法?
是的,可以这么理解,跟Vuejs里的插槽用法类似。
- 为什么用 render props
就像我们上面的思考题,子组件要传递name属性给孙组件,如果你用 props.children 的方式你做不到!
在实际项目开发中,可能某些情况下你也会碰到类似这种问题。
- 我可以子组件传给父组件,然后父组件再传给孙组件吗
可以,但是没必要,有更简单的为什么不用呢?如果是为了装逼当我没说
- 给我说说上面代码的流程是怎样的
- 父组件给子组件传递了render这个函数,这个函数会返回一个孙组件,并且这个函数接受一个形参
- 子组件在内部调用了这个render函数,并传递了自己身上的name属性
- render函数被调用,接收到子组件传递的name,随后render将其以props的方式添加到孙组件标签身上
- 孙组件通过props.name接收到render函数添加在其身上的name属性