什么是Props?在react中,类组件或者函数组件,父组件绑定在子组件标签里的属性或者方法最终会变成props传递给子组件。
import React from 'react';
class OnePropsComponents extends component{
render(){
return(
<div> hello i am onePropsComponents </div>
)
}
}
class TwoPropsComponents extends component{
render(){
const { children, mes, renderName, say, Component } = this.props
const renderFunction = children[0];
const renderComponent = children[1];
return(
<div>
{mes}
{renderFunction()}
{renderComponent()}
{renderName()}
<Component/>
<button onClick={()=>say()}> button </button>
</div>
)
}
}
class Index extends component{
constructor(props) {
super(props);
this.state = {
mes: ' I'm your boyfriend ',
};
// 方法注册
[
'say',
].forEach((method) => {
this[method] = this[method].bind(this);
});
}
say(){
this.setState({ mes: 'no! you daydreaming'})
}
render(){
const {mes}= this.state;
return(
<div>
<TwoPropsComponents
mes={mes} // props 作为渲染数据源
say={ this.say } // props 作为回调函数callback
Component={ OnePropsComponents } // props 作为一个组件
renderName={()=><div> i am shuaige </div>} // props 作为一个渲染函数
>
{()=><div>Content</div>} // render props 放在children属性上
<OnePropsComponents /> // 插槽组件
</TwoPropsComponents>
</div>
)
}
}
在标签内部的属性和方法会直接绑定在 props 对象的属性上,对于组件的插槽会被绑定在 props 的 Children 属性中。
React 对props的定义:
1、在组件层级:
父组件props可以把数据层传递给子组件渲染消费。
子组件可以通过props中的回调函数(callback)向父组件传递信息。还有一种可以将视图容器作为 props 进行渲染。
2、在react更新机制中:
在fiber调和阶段,diff是React更新的驱动器,在react中 props 可以作为组件是否更新的重要准则,props变化,组件即更新,
3、从插槽层面:
React 可以把组件的闭合标签里的插槽,转化成 Children 属性。
如何监听pros的改变:
在类组件中,使用生命周期函数componentWillReceiveProps/getDerivedStateFromProps监听props的变化,
在函数组件中,可以使用useEffect监听。
props重点 children模式:
1、插槽组件:
<FatherComponent>
<SonComponent /> // element 对象
</FatherComponent>
在FatherComponent组件中 可以通过 props.children属性 访问到SonComponent组件。
插槽组件的作用:
- 可以根据需要控制子组件(SonComponent)是否渲染。
- 父组件FatherComponent可以通过React.cloneElement强化 props,或者修改SonComponent的子元素。
2、render props模式:
<FatherComponent>
{(fatherProps)=><SonComponent {...fatherProps}/>}
</FatherComponent>
FatherComponent中props.children 访问到的是函数,不是element对象,在这种情况下children不能被直接渲染。
错误:
function FatherComponent(props) {
return props.children
}
正确:
function FatherComponent(props) {
const fatherProps={
name: 'zxy',
age: '18',
};
return props.children(fatherProps)
}
作用:
- 可以根据需要控制子组件(SonComponent)是否渲染。
- 可以将需要传给子组件(SonComponent) 的 props 直接通过函数参数的方式传递给执行函数 children 。
3、混合模式:
<FatherComponent>
<Component />
{(sonProps)=><Component {...sonProps} name={'zxy'} />}
</FatherComponent>
import React, {isValidElement} from 'react';
function ChildrenComponent(props){
return(
<div>我的名字叫`${props.name}`</div>
<div>{props.mes}</div>
)
}
function FatherComponent(props){
const fatherProps ={
name: 'zxy',
mes: 'i am react',
};
return props.children.map(item=>{
if(isValidElement(item)){ // isValidElement 判断是否是react 组件(element)
return cloneElement(item, {...fatherProps}, item.props.children) //针对节点(element)通过cloneElement 混入 props
}else if(typeof item==='function'){
return item(fatherProps) //针对函数 直接传递参数,执行函数。
}else{
return null;
}
})
}
function Index(){
return(
<FatherComponent>
<ChildrenComponent />
{(fatherProps)=><ChildrenComponent {...fatherProps} name={'最帅的男人'}/>}
</FatherComponent>
);
}
最终展示效果:
- 我的名字叫zxy
- i am react
- 我的名字叫最帅的男人
- i am react
props的使用:
1、混入
import React, { useEffect } from 'react';
function ChildComponent(props){
useEffect(()=>{
console.log(props) // 此处打印 props fatherProps的参数
},[])
return(
<div>我的父级组件混入了两个props</div>
)
}
function FatherComponent(props){
const fatherProps ={
name: 'zxy',
age: 18,
};
return(
<ChildComponent {...props} {...fatherProps} /> // 混入两个props
)
}
function Index(){
const rootProps ={
height: 178cm,
weight: 75kg,
};
return(
<FatherComponent {...rootProps}/>
)
}
2、抽离:
import React, { useEffect } from 'react';
function ChildComponent(props){
useEffect(()=>{
console.log(props) // 此处打印 没有 remark
},[])
return(
<div> i am zxy </div>
)
}
function FatherComponent(props){
const {remark, ...otherProps} = props;
return(
<ChildComponent {...otherProps} /> // 混入两个props
)
}
function Index(){
const rootProps ={
name: 'zxy',
age: 18,
height: 178cm,
weight: 75kg,
remark: '此处是要被抽离开的参数',
};
return(
<FatherComponent {...rootProps}/>
)
}
其他:
function ChildComponent(){return <div>子组件</div>}
function FatherComponent(){return <ChildComponent name='zxy' age=18 />}