Reac学习笔记#01#组件定义以及props、state的管理

React学习#01 组件的定义和 state 以及props的使用 官方文档

1. 特点

  • 数据单项绑定,自上而下流动
  • 支持组件封装和组件间的引用组合
  • JSX/TSX语法的使用
  • 使用虚拟DOM操作(diff更新【深度优先,同级比较】)

2. 组件定义

组件名称首字母必须大写,React以此来区别组件和普通的Html标签
2.1 通过class定义组件(React 16.8提供Hook,允许在函数组中使用state和其他React特性,官方建议以后使用函数声明组件,可只做参考理解)
class InputByClass extends React.Component<any, {value:string}>{
 //构造函数
  constructor(props:any) {
    console.log('construct')
    super(props);
    this.state = {value:''};
    this.onClick= this.onClick.bind(this);
  }

  //会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。
  // 返回一个对象来更新 state,如果返回 null 则不更新任何内容
  static getDerivedStateFromProps(prevProps: Readonly<any>, prevState: Readonly<{ value: string }>){
    console.log('state',prevState,'props',prevProps);
    return null;
  }
  onClick:(e:string)=>void = (e)=>{
    this.setState({value:e});
  }
  //组件触发更新渲染调用 入参原state 原props
  //hook类似实现 useEffect(()=>{}) 集成 componentDidUpdate+componentDidMount
  componentDidUpdate(prevProps: Readonly<any>, prevState: Readonly<{ value: string }>) {
    console.log('component update');
  }

  //组件触发更新前会调用 入参 更新后的props,state 返回boolean类型 true:更新 false:阻止更新
  //不常用 可用于于父组件重新时控制渲染子组件是否渲染
  //注意 hook类似实现 const Component = React.memo((props) => {组件},((prevProps, nextProps)=>{return true})); 结果返回判断相反 局限:只能判断props的更改
  shouldComponentUpdate(nextProps: Readonly<any>, nextState: Readonly<{ value: string }>): boolean {
    return true;
  }

  //组件挂载后调用,组件卸载前只会调用一次
  //hook类似实现 useEffect(()=>{},[])
  componentDidMount() {
    console.log('component did');
  }
 //卸载使用 用于清除处理
  //hook类似  useEffect(()=>{return ()=>{清除函数}) useEffect一个清除函数函数 更新和卸载时react会自动调用
  componentWillUnmount() {
    console.log('component unmount');
  }

  //渲染
  render() {
    console.log('render')
    return <input value={this.props.value} onChange={(e)=>{this.onClick(e.target.value)}}/>
  }
}
2.2通过函数定义组件(以后的主流方式)
const InputByFC:React.FC<any> = (props)=>{
  useEffect(()=>{
    console.log('hook component did')
  },[props])
  const [state,setState] = useState<{value:string}>({value:''});
  return( <input value={state.value} onChange={e=>{setState({value:e.target.value})}}/>)
}

3. state和props

3.1 state
state是React组件内部的状态,类似于Java类中的私有化变量,由于数据单向流向的特性,只能在自己组件的内部以及子组件中使用,当值发生变化会触发组件的重新渲染
tip:React关于state值的比较使用的是 ===,类似于Java,比较的是对象的地址而非内容,所以如果state类型为对象时,单纯改变某个属性值不会触发更新,需要重新复制一个新的对象
3.1.1 class中使用state
state可以使用两种方式赋值,构造函数使用this.state初始化赋值,其他函数中必须使用this.setState
/**
 *  显示state值  -> 按钮点击修改组件state数据(value值加一)->触发更新页面上至下重新渲染 ->state值显示为1 
 */
/
class ClassUseSate extends React.Component<any, {value:number}>{
    private value:number = 0;
    constructor(props:any) {
        super(props);
        this.state = {value:this.value}
    }
    render() {
        return(<div>{this.state.value}<button onClick={()=>{this.setState({value:this.value++})}}>+</button></div>)
    }
}
3.1.2 在函数组件中使用Hook变更state(不需要显示地定义state,由React来维护)
const FunctionUseState:React.FC<any> = (props)=>{
  const [value,setValue] = useState<number>(0);
  return(<div>{value}<button onClick={()=>{setValue(value+1)}}>+</button></div>);
}
3.1.3 比较
3.1.3.1 不同
  • state的定义语法不同,在class中由于继承的是React的Component,名称是约定好的,赋值和初始化只能使用this.state或者this.setSate
    但是在函数式组件中,可以使用useSate方法获取React对内部state管理的方法从而控制组件的更新
  • class组件中state只会一个对象(更新时会合并,Hook不会,可以在使用Hook的方法中合并后再设置state达到类似效果),而在函数式组件中useState可以做拆分,分别对不同的情况定义不同的state使组件的控制更加细化
3.1.3.2 相同
  • 本质是相同的,都是对React内部的state进行维护,只是定义方法不同
3.1.3.3 函数式组件+Hook的优势和不足
  • 优势:使用函数定义代替class的定义,使用Hook解决了对组件内部函数和state的调用和维护(例如 uesSate实现了对state的管理,useEffect实现了类似于生命周期方法的调用等),通过使用函数定义,Hook管理使得函数
    式组件相较于class定义的组件更加易懂,简便。
  • 不足:官网提示目前暂时还没有对应不常用的 getSnapshotBeforeUpdate,getDerivedStateFromError 和 componentDidCatch 生命周期的 Hook 等价写法,但会计划尽早把它们加进来。
3.2 props
props为组件的入参,不管是函数式定义,还是class定义都应该是只读的,另外class定义必须调用父类super的方法
// props为组件参数
//class定义
class ClassProps extends React.Component<any, any>{
  constructor(props:any) {
    super(props);
    this.state = {};
  }
  render() {
    return (<></>);
  }
}
//函数定义 
const FunctionPros:React.FC = (props:any)=>{
return(<></>);
}

4. 总结

虽然class定义的组件会继续兼容,但是鉴于函数式组件+Hook已经能处理大部分场景,而且各大主流框架也开始采用这种方法,class写法可用于结合理解组件的生命周期,
维护旧项目只做了解即可,之后的使用还是建议使用函数组件+Hook方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值