创建
在SRC目录中,创建一个 xxx.jsx 的文件,就是要创建一个组件;我们在此文件中,创建一个函数并导出,让函数返回JSX视图「或者JSX元素、virtualDOM虚拟DOM对象」;这就是创建了一个“函数组件”。函数组件可以接收父组件传过来的属性和子组件,并把他们一起放在props对象里方便函数组件接收。普通属性名为传递的名字,子组件放在children数组里,并存放其虚拟Dom。
export default Demo=(props)=>{
let {arr1,arr2,children}=props
return <div>测试</div>
}
一个接收的props例子
调用
基于ES6Module规范,导入创建的组件「可以忽略.jsx后缀名」,然后像写标签一样调用这个组件即可
<Component/> 单闭合调用
<Component> ... </Component> 双闭合调
调用组件的时候,我们可以给调用的组件设置(传递)各种各样的属性
<DemoOne title="我是标题" x={10} data={[100, 200]} className="box" style={{ fontSize: '20px' }} />
+ 如果设置的属性值不是字符串格式,需要基于“{}胡子语法”进行嵌套
+ 调用组件的时候,我们可以把一些数据/信息基于属性props的方式,传递给组件!!
命名:组件的名字,我们一般都采用PascalCase「大驼峰命名法」这种方式命名
渲染机制的不同
基于root.render把virtualDOM变为真实的DOM的时候,type值不再是一个字符串,而是一个函数了,此时:
+ 把函数执行 -> DemoOne()
+ 把virtualDOM中的props,作为实参传递给函数 -> DemoOne(props)
+ 接收函数执行的返回结果「也就是当前组件的virtualDOM对象」!!!!
+ 最后基于render把组件返回的虚拟DOM变为真实DOM,插入到#root容器中!!
属性props的处理
调用组件,传递进来的属性是“只读”的「原理:props对象被冻结了」Object.isFrozen(obj) =>true 如果确实想修改传过来的值就用另一个值接收。
作用:父组件(index.jsx)调用子组件(DemoOne.jsx)的时候,可以基于属性,把不同的信息传递给子组件;子组件接收相应的属性值,呈现出不同的效果,让组件的复用性更强!!
虽然对于传递进来的属性,我们不能直接修改,但是可以做一些规则校验
+ 设置默认值
函数组件.defaultProps = {
x: 0,
......
};
import PropTypes from 'prop-types'; //这是一个包需要下载专门解决规定类型问题,感觉以后TS可以解决
函数组件.propTypes = {
// 类型是字符串、必传
title: PropTypes.string.isRequired,
// 类型是数字
x: PropTypes.number,
// 多种校验规则中的一个
y: PropTypes.oneOfType([
PropTypes.number,
PropTypes.bool,
])
};
但是注意函数组件是“静态组件”,它在第一次渲染完毕后就不会更新,就算在函数组件中更新数值视图也不会更新,除非在父组件中重新调用这个函数组件。 在真实项目中大部分都有可以让组件更新的需求,这种就叫动态组件,例如类组件和Hooks组件。