二,组件
1,组件有两种定义方式:class(类组件)和使用函数(函数组件)
class:
- 继承自React.Component
- 内部必须定义render方法,返回该组件UI的React元素
使用函数:
接收props作为参数,返回代表这个组件UI的React元素结构,
例如:
function Welcome(props) { return <h1>hello,{props.name}</h1>; }
2,props和state
例如做一个展示用户的列表,通过点击按钮给用户点赞:
props:
用于把父组件中的数据或方法传递给子组件。props是只读的,不能在组件内部修改props。
在父组件中引用子组件User:<User name='sxww' age='26' /> ,此时User的props为props={name: 'sxww',age: '26'},User中使用props:
import React, { Component } from "react";
class User extends Component {
constructor(props){
super(props);//实际上调用了React.Component这个class的constructor方法,用来完成React组件的初始化工作
}
render() {
const props = this.props;
return (
<div>
<div><label>姓名:</label><span>props?.name</span></div>
<div><label>年龄:</label><span>props?.age</span></div>
</div>
)
}
}
export default User;
state:
组件的state是组件内部的状态,在constructor中通过this.state定义组件的初始状态,通过调用this.setState方法改变组件状态。
react组件可以看做是一个函数,函数的输入是props和state,输出是组件的UI
UI = Component(props,state)
3,有状态组件和无状态组件
如果一个组件内部状态是不变的,则不用state,这样的组件称为无状态组件。
一个组件内部状态会发生变化,则需要使用state,这样的组件称为有状态组件。
定义无状态组件应该尽量将其定义为无状态组件。无状态组件不要关心状态的变化,只聚焦于UI的展示。这样,上述代码中获取用户信息,姓名、年龄、点赞数都放在父组件(有状态组件),handleClick也放到父组件,User只展示用户信息。
React应用组件设计的一般思路是,通过定义少数的有状态组件管理整个应用的状态变化,并且将状态通过props传递给其余的无状态组件,由无状态组件完成页面绝大部分UI的渲染工作。总之,有状态组件主要关注处理状态变化的业务逻辑,无状态组件主要关注组件UI的渲染。
4,属性校验和默认属性
组件内部声明props应该暴露出那些接口,React提供了ProTypes这个对象,用于校验组件属性的类型。
import PropTypes from 'prop-types'; class User extends React.Component{ } User.propTypes = { info:PropTypes.object,
handleClick:PropTypes.func }
当使用PropTypes.object或PropTypes.array校验属性时,无法校验对象的结构和数组元素的类型,这种情况下,我们可以使用PropTypes.shape或PropTypes.arrayOf。如果属性是组件的必须属性,则需要在PropTypes的类型属性上调用isRequired。
User.propTypes = {
info:PropTypes.shape({
name: PropTypes.string,
age: PropTypes.number
}).isRequired,
handleClick:PropTypes.func.isRequired,
photos: PropTypes.arrayOf(PropTypes.string),
}
React还提供了为组件属性指定默认值的特性,这个特性通过defaultProps实现,当组件属性未被赋值,组件会使用defaultProps的默认属性:
User.defaultProps = { info:{
name: 'sxww', age: 26 } }
5,组件样式
为组件添加样式的方法有两种:外部CSS样式表和内联样式。
外部CSS样式表:和平时开发web应用时使用外部css文件相同,唯一区别在react元素使用className来代替class作为选择器。
function Welcome(props) { return <h1 className="foo">hello,{props.name}</h1>; }
//css样式表
.foo{...}
class名称冲突的解决方案:可以使用CSS Modules,CSS Modules会对样式文件中的class名称重新命名从而保证其唯一性。(https://github.com/css-modules/css-modules)
内联样式:css in js,样式的属性名必须使用驼峰命名法。
function Welcome(props) { return <h1 style={{height:'50px',fontSize:'14px'}}>hello,{props.name}</h1>; }
6,组件和元素
React组件是由若干React元素组建而成的。一个React组件是一个class或函数,接收一些属性作为输入,返回一个React元素。