在 React 世界里,一切皆组件,我们写的 React 项目全部起源于组件。组件可以分为两类,一类是类( Class )组件,一类是函数( Function )组件。
React组件结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class testClass { sayHello=()=>console.log('hello, world') }
export default class FreshHot extends React.PureComponent<Partial<any>> { state={ message:`hello ,world!` } sayHello=()=> this.setState({ message : 'hello, change' }) componentDidMount() { } public render(){ return <div onClick={ this.sayHello } > { this.state.message } </div> } }
function testFunc (){ return 'hello, world' }
function FuncComponent(props){ const { dataList } = props const [ message , setMessage ] = useState('hello,world') return <div onClick={ ()=> setMessage('hello, change') } >{ message }</div> }
|
组件本质上就是类和函数,但是与常规的类和函数不同的是,组件承载了渲染视图的 UI 和更新视图的 setState 、 useState 等方法
react组件是在 React调和渲染fiber节点的时候分别被实例化或执行的,分别有对用的脚本去执行,具体可以关注react-reconciler
。
类组件
生命周期:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| class App extends React.Component { constructor(props) { super(props); console.log("constructor")
this.onClickHandler = this.onClickHandler.bind(this); } componentWillMount() { console.log("componentWillMount") } componentDidMount() { console.log("componentDidMount") } componentWillUnmount() { console.log("componentWillUnmount") } componentWillReceiveProps() { console.log("componentWillReceiveProps") } shouldComponentUpdate() { console.log("shouldComponentUpdate") return true } componentWillUpdate() { console.log("componentWillUpdate") } componentDidUpdate() { console.log("componentDidUpdate") }
onClickHandler() { console.log("onClickHandler") this.forceUpdate(); }
render() { console.log("render") return ( <button onClick={this.onClickHandler}> click here </button> ); } }
ReactDOM.render(<App />, document.getElementById("react-container") );
|
在 class 组件中,除了继承 React.Component ,底层还加入了 updater 对象,类组件执行构造函数过程中会在实例上绑定 props 和 context ,初始化置空 refs 属性,原型链上绑定setState、forceUpdate 方法。
函数组件
函数组件直接调用执行,不会创建实例,原型上的属性方法无效。依靠hook实现转态存储能力。
选择函数组件的原因
函数组件:纯函数,输入props,输出jsx,没有实例,没有this,没有state,没有生命周期,hook出现就不一样了,函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可。为了提高性能,尽量使用函数组件。函数组件代码更简洁,性能很好;
组件通信
React 一共有 5 种主流的通信方式:
- props 和 callback 方式
- ref 方式。
- React-redux 或 React-mobx 状态管理方式。
- context 上下文方式。
- event bus 事件总线。
props 和 callback 可以作为 React 组件最基本的通信方式,父组件可以通过 props 将信息传递给子组件,子组件可以通过执行 props 中的回调函数 callback 来触发父组件的方法,实现父与子的消息通讯。
增强组件的方式
- 类继承
- 自定义 hooks
- 高阶组件 hoc