React学习总结 10.16

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

1.几种创建组件的方式

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

组件创建方式

  1. React.createClass // 已经弃用(console直接把React对象打印出来可以加深对API的理解)
const Nav = React.createClass({
        render: function() {
            return ( 
                <ul>
                    <li>首页</li>
                    <li>我的</li>
                </ul> 
            ) 
        } 
      });

// 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 (
        <div> {map(list, (item) => <div>{item.name}</div>)} </div> 
    ); 

}

组件通讯

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

class Tim extends Component {
  constructor(props) {
    super(props)
  }
  render() {
    return (
      <div>{this.props.notice}</div>
    )
  }
}
class Teacher extends Component {
  render() {
    return (
      <Tim notice="明天来上课"></Tim>
    )
  }
}

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

场景: 操作DOM触发

class Tim extends Component {
  constructor(props) {
    super(props)
  }
  render() {
    return (
      <div><input onChange={this.props.handleEmail}/></div>
    )
  }
}


class Teacher extends Component {
    handleEmail(event){
        console.log(event.target.value)
    }
  render() {
    return (
      <Tim handleEmail={this.handleEmail.bind(this)}></Tim>
    )
  }
}



场景: 在函数回调触发


class Tim extends Component {
  constructor(props) {
    super(props)
  }
  handleClick(){
    this.props.handleEmail('他们已经干我了!')
  }
  render() {
    return (
      <div>
        <div onClick={this.handleClick.bind(this)} > 快来干我!</div>
      </div>
    )
  }
}


class Teacher extends Component {
    handleEmail(event){
        console.log(event)
    }
  render() {
    return (
      <Tim handleEmail={this.handleEmail.bind(this)}></Tim>
    )
  }
}

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


class Tim extends Component {
  constructor(props) {
    super(props)
  }
  handleClick() {
    this.props.handleEmail('我爸是局长!')
  }
  render() {
    return (
      <div>
        <div onClick={this.handleClick.bind(this)} > 快来干我!</div>
      </div>
    )
  }
}


class Teacher extends Component {
  handleEmail(event) {
    this.props.handleText(event)
    console.log("Teacher" + event)
  }
  render() {
    return (
      <Tim handleEmail={this.handleEmail.bind(this)}></Tim>
    )
  }
}

class Boss extends Component {
  handleText(event) {
    console.log("Boss" + event)
  }
  render() {
    return (
      <Teacher handleText={this.handleText.bind(this)}></Teacher>
    )
  }
}



兄弟组件通讯

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

//子组件
class Tim extends Component {
  constructor(props) {
    super(props)
  }
  handleClick() {
    this.props.handleEmail('Jerry你是我最好的朋友!')
  }
  render() {
    return (
      <div>
        <div onClick={this.handleClick.bind(this)} > 快来点我吧!</div>
      </div>
    )
  }
}

//父组件
class Teacher extends Component {
  constructor() {
    super()
    this.state = {
      notice: ""
    }
  }
  handleEmail(val) {
    this.setState({
      notice: val
    })
    console.log(val)
  }
  render() {
    return (
      <div>
      <Tim handleEmail={this.handleEmail.bind(this)}></Tim> 
      <Jerry notice = {this.state.notice} > </Jerry>
      </div>
    )
  }
}

// 子组件
class Jerry extends Component {
  constructor(props) {
    super(props)
  }
  render() {
    return (
      <div>
        <div>{this.props.notice}</div>
      </div>
    )
  }
}

生命周期

初始化
  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 <WrappedComponent
                {...Sex}
            />;
    }
  }
// 使用
const Container = HOC(PageIndex);

<Container name="zhang"/>

// PageIndex print

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


  1. 提升state

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


class WrappedComponent extends Component {
  render() {
    return <div className="u-box" {...this.props.name} ></div>;
  }
}

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 <WrappedComponent {...newProps} />;
    }
  }


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 <Loading/>
      }
    }
  }

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,924评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,781评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,813评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,264评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,273评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,383评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,800评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,482评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,673评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,497评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,545评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,240评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,802评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,866评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,101评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,673评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,245评论 2 341

推荐阅读更多精彩内容

  • React.js 小书学习 之 【使用 JSX 描述 UI 信息】 从 JSX 到页面 过程图解:JSX 到页面过...
    zdlucky阅读 1,266评论 0 20
  • 说在前面 关于 react 的总结过去半年就一直碎碎念着要搞起来,各(wo)种(tai)原(lan)因(le)。心...
    陈嘻嘻啊阅读 6,840评论 7 41
  • 作为一个合格的开发者,不要只满足于编写了可以运行的代码。而要了解代码背后的工作原理;不要只满足于自己的程序...
    六个周阅读 8,414评论 1 33
  • 在目前的前端社区,『推崇组合,不推荐继承(prefer composition than inheritance)...
    Wenliang阅读 77,647评论 16 125
  • Day23 170627 宝剑六 宝剑六 加上彩虹牌上的“在生命之流里,我感到安全” 感觉左边的牌就是在生命之流中...
    蜗子阅读 309评论 0 0