React基础|青训营笔记

50 阅读2分钟

这是我参与「第五届青训营 」笔记创作活动的第6天。

本堂课重点内容

本堂课学习了React的设计思路以及基本使用。

详细知识点介绍

设计思路

一言以概之,React的主要设计思路包括:

  • 响应式编程

    • 对于事件来说,我们执行既定的回调,之后状态进行变更,然后UI进行更新
  • 组件化

    • 组件是组件的组合/原子组件
    • 组件内拥有状态,外部不可见
    • 父组件可将状态传递到子组件内部
  • 状态归属

    • 当前状态归属于两节点向上寻找到的最近的祖宗节点

类组件

以一个基本的tab栏为例

基本代码结构(父):

 import React, { Component } from 'react'
 export class App extends Component{
     constructor() {
         super()
 ​
         this.state = {
             titles: ["流行", "新款", "精选"],
             tabIndex: 0
         }
     }
     tabClick(tabIndex){
         this.setState({tabIndex})
     }
     render(){
         const {titles,tabIndex} = this.state
         return(
             <div className='app'>
                 <TabControl titles={titles} tabClick={i => this.tabClick(i)} />
                 <h1>{titles[tabIndex]}</h1>
             </div>
         )
     }
 }

基本代码结构(子):

 import React, { Component } from 'react'
 import "./style.css"
 ​
 export class TabControl extends Component {
   constructor() {
     super()
     this.state = {
       currentIndex: 0
     }
   }
   itemClick(index) {
     this.setState({ currentIndex: index })
     this.props.tabClick(index)
   }
   render() {
     const { titles } = this.props
     const { currentIndex } = this.state
 ​
     return (
       <div className='tab-control'>
         {
           titles.map((item, index) => {
             return (
               <div 
                 className={`item ${index === currentIndex?'active':''}`} 
                 key={item}
                 onClick={e => this.itemClick(index)}
               >
                 <span className='text'>{item}</span>
               </div>
             )
           })
         }
       </div>
     )
   }
 }
 ​
 export default TabControl

对于render函数来说,当没有stateprops变化时,我们不需要再次运行render函数,所以我们可以使用pureComponent(类组件)或memo(函数式组件)来进行性能优化。

当我们使用class来创建React组件时,还有一个很麻烦的事情:this的指向。为了保证this的指向正确,我们通常要采用箭头函数,或者使用this.handleClick = this.handleClick.bind(this)这种代码,增加了心智负担。

函数式组件

对于无状态的函数式组件来说,我们可以通过使用Hooks来保存状态,同时大大简化代码。

 import { useState } from 'react';
 ​
 function Example(props) {
     const [count, setCount] = useState(0);
     const {name} = props;
     return (
         <div>
             <p>{name} clicked {count} times</p>
             <button onClick={() => setCount(count + 1)}>
                 Click me
             </button>
         </div>
     );
 }

对于hooks来说,react规定我们必须把hooks写在函数的最外层,不能写在ifelse等条件语句中,来确保hooks的执行顺序一致。

而对于类组件中的生命周期钩子,我们可以使用useEffect来进行替代,对每一个副作用函数使用一个单独的useEffect钩子,这样一来使代码的逻辑也变得更加清晰。

useEffect:

  • 第一个参数传递副作用函数
  • 副作用函数return的函数来清除副作用影响
  • 第二个参数规定副作用的范围数组