特点:用ES6面向对象语法,有生命周期,有this,有state,有上下文,有ref,永远不能使用Hooks.
缺点:相对函数组件,类组件性能相对较差。
class A extends Component { constructor (props) { super(props) // 定义声明式变量 this.state = { num: 1 } } componentDidMount () { console.log('---页面渲染完成') this.refs.box.style.color = 'red' } componentDidUpdate () { console.log('---页面更新完成') } add () { this.setState((state)=>({num: state.num+1})) } // 成员方法 render () { console.log('---render/rerender') console.log('---props', this.props) const { num } = this.state // 返回视图模板(JSX) return ( <h1 ref='box'>类组件 {num} <span onClick={()=>this.add()}>自增</span></h1> ) } } export default A
特点:用函数编程,没有生命周期,没有state,没有this,没有上下文,没有ref,自React(16.8)版本之后可以使用Hooks,可以使用Hooks API在函数组件模拟没有生命周期,没有state,没有this,没有上下文,没有ref缺失的特性。
优点:相对于类组件,性能更好。
注意:无论是类组件还是函数组件,都有props(父子通信的纽带),在类组件中使用this.props访问,在函数组件中它的入参就是props。
注意:在React(16.8)之前是没有Hooks的,在React(16.8)之后才新增的Hooks。
function B (props) { console.log('---props', props) // 模拟state声明变量 const [num, setNum] = useState(1) // 使用ref const box = useRef(null) // 模拟生命周期 useEffect(()=>{ console.log('---页面渲染/更新完成') if (num === 1) { box.current.style.color = 'blue' } }, [num]) return ( <h1 ref={box}>函数式组件 {num} <span onClick={()=>setNum(num+10)}>自增</span></h1> ) } export default B
在JSX可以嵌套表达式,使用{}来嵌套,在JSX视图中凡是动态的变量(表达式)都使用{}包裹起来。
JSX是变量,也是表达式,所以JSX元素可以作为函数的入参,也可以作为函数的返回值,还可以用在if或for循环中。
JSX语法新增的三个属性:key(用于列表渲染),ref(快捷的Dom方式),dangerouslySetInnerHTML(用于渲染HTML片段)
在JSX中,使用{}渲染后端接口数据,默认支持反注入攻击(XSS)
JSX是对象,因为JSX变量是React.createElement()的返回值,这个返回值就是对象结构,所以JSX是对象。这中JSX对象就是"Fiber单元",很多嵌套“Fiber单元”就构成了“Fiber树”(双向链表)。
在JSX中,向子组件传递props时,支持属性展开语法 <Child {...cPorps} />
在使用自定义组件时,哪些被自定义组件所嵌套的内容,在子组件中使用props.children来接收。props.children可以说基本数据类型,引用数据类型,函数。
在JSX中默认可以支持对数组直接渲染 <div>{ [<div />, true, null, 100, {a:1,b:2}, [1,2,3]] }</div>
在JSX中,使用{}渲染Boolean,null,undefined都会被忽略。以下显示的结果相同。
<div /> <div></div> <div>{false}</div> <div>{null}</div> <div>{undefined}</div> <div>{true}</div>