美文网首页
React学习总结 10.16

React学习总结 10.16

作者: HelloAndyZhang | 来源:发表于2018-10-16 18:57 被阅读0次

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

    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父组件传入的值实现显示隐藏。
    
    

    相关文章

      网友评论

          本文标题:React学习总结 10.16

          本文链接:https://www.haomeiwen.com/subject/bpxkzftx.html