两组组件定义
- 类组件(class组件)
特点:用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
- 函数组件(自React诞生之初就有的写法)
特点:用函数编程,没有生命周期,没有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(JavaScript XML)语法,由Facebook发布的,浏览器是不支持这种语法。
- 在编写React组件视图结构时,JSX是可选的,可以使用React.createElement('tag',{},[]编写视图结构)官方推荐使用JSX。
- JSX语法最终会被@babel/preset-react进行编译,编译的结果就是React.createElement()语法。
- JSX元素:本质上就是React.createElement()的返回值,是变量,也是对象,并且是不可变的对象。
- 为什么JSX元素是不可变对象?因为JSX元素最终会被渲染成真实DOM,所以不能直接操作“原材料”,而是只能使用声明式变量。
- 什么是元素?由JSX语法或React.createElement()返回的结果叫做元素,元素就是组件实例化的对象。
- 什么是组件?由class或function定义的东西叫做组件。
深入理解JSX语法细节
在JSX可以嵌套表达式,使用{}来嵌套,在JSX视图中凡是动态的变量(表达式)都使用{}包裹起来。
JSX是变量,也是表达式,所以JSX元素可以作为函数的入参,也可以作为函数的返回值,还可以用在if或for循环中。
- JSX语法三个变化属性:className(class),tabIndex(tabindex),htmlFor(for)
JSX语法新增的三个属性:key(用于列表渲染),ref(快捷的Dom方式),dangerouslySetInnerHTML(用于渲染HTML片段)
- 内联style语法: <div style={{ cssKey1: 'cssValue1', cssKey2: 'cssValue2' }} />
- className语法: <div className='box' className={`${cc} ff`} />
在JSX中,使用{}渲染后端接口数据,默认支持反注入攻击(XSS)
JSX是对象,因为JSX变量是React.createElement()的返回值,这个返回值就是对象结构,所以JSX是对象。这中JSX对象就是"Fiber单元",很多嵌套“Fiber单元”就构成了“Fiber树”(双向链表)。
- JSX支持点语法: React.Componenet、<React.Fragment />、<Qf.Button />
在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>