React学习总结 10.16

觉得比较重要的几个点简单做下笔记方便以后查

1.几种创建组件的方式

  1. 组件生命周期相关的钩子
  2. 父子组件通讯
  3. 高阶组件的使用和定义 HOC

组件创建方式

  1. React.createClass // 已经弃用(console直接把React对象打印出来可以加深对API的理解)
const Nav = React.createClass({
        render: function() {
            return ( 
                
  • 首页
  • 我的
) } }); // React 16.5对外暴露的方法 { Children: {map: ƒ, forEach: ƒ, count: ƒ, toArray: ƒ, only: ƒ} Component: ƒ Component(props, context, updater) Fragment: Symbol(react.fragment) PureComponent: ƒ PureComponent(props, context, updater) StrictMode: Symbol(react.strict_mode) cloneElement: ƒ cloneElementWithValidation(element, props, children) createContext: ƒ createContext(defaultValue, calculateChangedBits) createElement: ƒ createElementWithValidation(type, props, children) createFactory: ƒ createFactoryWithValidation(type) createRef: ƒ createRef() forwardRef: ƒ forwardRef(render) isValidElement: ƒ isValidElement(object) unstable_AsyncMode: Symbol(react.async_mode) unstable_Profiler: Symbol(react.profiler) version: "16.5.2" }
  1. class Nav extends React.Component 通过继承Component对象

class Nav extends Component{ };

class Nav extends React.Component{}

两种方法一样与模块导入方式有关
import * as React from "React";  // 导入全部对象属性和方法 只能使用第一种,通过React.Component才能继承

import React,{Component} from 'React' //可以使用以上任意方式继承方法属性

import { ObjOne, ObjTwo} from 'Obj' 可以引入多个方法

  1. function Nav (){} 通过函数定义无状态组件

无状态组件:适合用来声明没有组件生命周期方法并且没有内部状态的组件。

function Nav({ list }) { 
    return (
        
{map(list, (item) =>
{item.name}
)}
); }

组件通讯

父组件(Teacher) ---> 子组件(Tim) props

class Tim extends Component {
  constructor(props) {
    super(props)
  }
  render() {
    return (
      
{this.props.notice}
) } } class Teacher extends Component { render() { return ( ) } }

子组件(Tim) ---> 父组件(Teacher) 函数回调

场景: 操作DOM触发

class Tim extends Component {
  constructor(props) {
    super(props)
  }
  render() {
    return (
      
) } } class Teacher extends Component { handleEmail(event){ console.log(event.target.value) } render() { return ( ) } } 场景: 在函数回调触发 class Tim extends Component { constructor(props) { super(props) } handleClick(){ this.props.handleEmail('他们已经干我了!') } render() { return (
快来干我!
) } } class Teacher extends Component { handleEmail(event){ console.log(event) } render() { return ( ) } }

子组件(Tim) ---> 父组件(Teacher) --->爷爷组件(Boss) 函数回调


class Tim extends Component {
  constructor(props) {
    super(props)
  }
  handleClick() {
    this.props.handleEmail('我爸是局长!')
  }
  render() {
    return (
      
快来干我!
) } } class Teacher extends Component { handleEmail(event) { this.props.handleText(event) console.log("Teacher" + event) } render() { return ( ) } } class Boss extends Component { handleText(event) { console.log("Boss" + event) } render() { return ( ) } }

兄弟组件通讯

Redux || 子组件(Tim) ----> (函数回调) 父组件(Teacher) ----> (props) 子组件(Jerry)

//子组件
class Tim extends Component {
  constructor(props) {
    super(props)
  }
  handleClick() {
    this.props.handleEmail('Jerry你是我最好的朋友!')
  }
  render() {
    return (
      
快来点我吧!
) } } //父组件 class Teacher extends Component { constructor() { super() this.state = { notice: "" } } handleEmail(val) { this.setState({ notice: val }) console.log(val) } render() { return (
) } } // 子组件 class Jerry extends Component { constructor(props) { super(props) } render() { return (
{this.props.notice}
) } }

生命周期

初始化
  1. getDefaultProps()

设置默认的props,也可以用dufaultProps设置组件的默认属性.

  1. getInitialState()

在使用es6的class语法时是没有这个钩子函数的,可以直接在constructor中定义this.state。此时可以访问this.props

  1. componentWillMount()

组件初始化时只调用,以后组件更新不调用,整个生命周期只调用一次,此时可以修改state。

  1. render()

react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行。此时就不能更改state了。

更新
  1. componentDidMount() * 常用

组件渲染之后调用,只调用一次。此时可进行请求数据,返回数据setState后组件会重新渲染 。此时this.getDOMNode()访问真实的DOM元素。此时可以使用其它类库操作DOM。

  1. componentWillReceiveProps(nextProps) * 常用

组件初始化时不调用,组件接受父组件改变后的props时调用。

  1. shouldComponentUpdate(nextProps, nextState)

唯一用于控制组件重新渲染的生命周期,react性能优化非常重要的一环。 组件接受新的state或者props时调用,我们可以设置在此对比前后两个props和state是否相同,如果相同则返回false阻止更新,因为相同的属性状态一定会生成相同的dom树,这样就不需要创造新的dom树和旧的dom树进行diff算法对比,节省大量性能,尤其是在dom结构复杂的时候

  1. componentWillUpdata(nextProps, nextState)

组件初始化时不调用,只有在组件将要更新时才调用, 此时可以修改state ?

  1. componentDidUpdate()

组件更新完毕后,组件初始化时不调用,组件更新完成后调用,此时可以获取dom节点。

卸载

  1. componentWillUnmount()

组件将要卸载时调用,一些事件监听和定时器需要在此时清除。

高阶组件的使用和定义 (HOC)

概念

  • 高阶组件通过包裹被传入的React组件,经过一系列处理,最终返回一个相对增强的 React 组件,供其他组件调用。一个高阶组件只是一个包装了另外一个 React 组件的 React 组件。
  • 属性代理(Props Proxy)( 高阶组件操控传递给 WrappedComponent 的 props,)

使用

  1. 操作props (对需要传入的props进行拦截,添加、删除、修改)
// 封装

const HOC = (WrappedComponent) =>
  class WrapperComponent extends Component {
    render() {
      const msg = {
        ...this.props,
        Sex: 'Male'
      }
      return ;
    }
  }
// 使用
const Container = HOC(PageIndex);



// PageIndex print

{
    Sex: "Male"
    name: "Zhang"   
}


  1. 提升state

把被包裹组件(WrappedComponent)中的状态提到包裹组件中 通过props把事件传递,然后通过回调把被包裹组件中state传出来


class WrappedComponent extends Component {
  render() {
    return 
; } } const HOC = (WrappedComponent) => class extends Component { constructor(props) { super(props); this.state = { name: '', }; this.onNameChange = this.onNameChange.bind(this); } onNameChange(event) { console.log(event) } render() { const newProps = { name: { onClick: this.onNameChange, }, } return ; } } const Container = HOC(WrappedComponent)
  • 反向继承(高阶组件继承(extends)WrappedComponent)

//对所有页面增加Loading(反向继承方式可以获取父组件得props、state。实用性比较强,避免很多重复的劳动)
const HOC = (WrappedComponent) =>
  class HOC extends WrappedComponent {
    constructor(props) {
      super(props);
      console.log(props)
    }
    render() {
      if (!this.state.isLoading) {
        // 反向继承
        return super.render()
      } else {
        return 
      }
    }
  }

// 使用
const Container = HOC(PageIndex);

Vue中实现则需要通过插槽的方式把所有页面插入到该组件中,通过子组件watch父组件传入的值实现显示隐藏。

你可能感兴趣的:(React学习总结 10.16)