美文网首页React
【React】组件

【React】组件

作者: Qingelin | 来源:发表于2019-10-17 23:44 被阅读0次

    1. class组件

    复杂的组件,需要记录自己内部状态的话,使用class组件,因为function不能有局部变量和方法,而class可以有。

     //一部分页面标签放在一个函数里
    function App(){
      return (
        <div>
          app
        </div>
      )
    }
    //必须继承组件,添加extends React.Component
    class App2 extends React.Component{
    
      constructor(props){ //声明变量必须写在constructor里面
        super(props)//使用constructor必须写这个
        this.state= {  变量必须写在this.state里
           number:0
        }
      }
     
          
      add(){
        this.setState({
          number: this.state.number += 1
        })
      }
      render(){ //局部render
        return (
          <div>
            app 2 {this.props.name}
            <div>
              {this.state.number} 
              <button onClick={this.add.bind(this)}>+</button>
            </div>
          </div>
        )
      }
    }
    
    
    render()
    
    function render(){
      
      ReactDOM.render(
          <App2 name="qinglin" age="18"/>, 
          document.querySelector('#root'))
    }
    

    2. 函数组件

    把组成一部分页面的标签写在一个函数中,叫做函数组件。

    • 在上一节中说过React的作者的第一个创举,组件当中体现了第二个创举:标签的名字就是函数,标签的属性的key value 理解成一个对象,函数的参数就是这个对象。
      例如:
    let number = 0
    
    add =()=>{
      number += 1
      render()
    }
    
    minus =()=>{
      number -= 1
      render()
    }
     
     //一部分页面标签放在一个函数里
    function App(){
      return (
        <div>
      //这里的Box1标签就是函数,代表页面一部分的标签,标签的属性其实是对象,下面两个函数的参数obj就是这个对象
          <Box1 name="加一" />
        </div>
      )
    }
    
    function Box1(obj){
      return (
        <div class="parent">
        我的名字是{obj.name}
        <hr />
          <span>{number}</span>
          <button onClick={add}>+</button>
          <button onClick={minus}>-</button>
        </div>
      )
    }
    
    
    render()
    
    function render(){
      
      ReactDOM.render(
          //虚拟DOM,本质就是对象
          
          
          <App/>, //这是XML语法
          
          
          document.querySelector('#root'))
    }
    
    
    
    
    

    【涉及到的知识点】

    • this.setState ————

      • 优点:回对更新优化,会把多次更新结果只进行一次渲染就能完成
      • 缺点:同时带来了弊端,有时候会有多个执行语句时异步更新
    • DOM diff ——— react每次修改变量都会自动智能地去局部更新页面内,更新之前都会把最新信息跟之前相比较,然后只更新有变化的部分,这种非常友好的过程叫DOM diff。


    3. 组件通信

    3.1 父子通信
    • 子组件向父级组件传递信息:
      原理:父级组件传一个函数,子元素在必要时(回调)调用通信函数(通信函数被调用时还可以传给它一些参数页面中可以渲染出来)。
       //代码示例
    这个App是父元素
    class App extends React.Component{ 
        constructor(){
           this.state={
              ...
          }
          this.setState({
            ....
          })
        }
    
        通信函数1(){}
        通信函数2(){}
        //App父级组件会把两个通信函数分别传给子级组件div1 和 div2
        render(){
          return (
            <div>
              <div1 f1 = {this.通信函数1.bind(this)}></div1>
              <div1 f2 = {this.通信函数2.bind(this)}></div1>
            </div>
          )
        }
    }
    
    //两个div子组件会调用通信函数
    
    //这个div1是子元素
    class div1 extends React.Component{
        ....
        this.state.通信函数1()
    }
    //这个div2也是子元素
    class div2 extends React.Component{
       ....
      this.state.通信函数2()
    }
    
    • 父级组件向子级组件传递信息:
      父级组件通过 props 给子组件的某个属性传一个值
        function App(){
            return (
                  <div>
                       <span message="你好!"/>
                  </div>
            )
        }
        
      function span(props){
          return (
            <p>子级组件得到的信息是:{props.message}</p>
          )
       }
      
      ReactDOM.renfer(
         <App />,
         document.querySelector("root")   
      )
      

    3.1 爷孙通信

    原理:爷爷级组件把一个或多个函数传给父级组件,父级组件再把这个函数透传给子级组件,最后自己组建调用这个函数。

    代码示例,
    这个App是父元素
    class App extends React.Component{ 
        constructor(){
           this.state={
              ...
          }
          this.setState({
            ....
          })
        }
    
        通信函数1(){}
        通信函数2(){}
        //App爷爷级组件会把两个通信函数分别传给父级组件parent
        render(){
          return (
            <div>
              <parent  
                      success1={this.success1.bind(this)}
                       success2={this.success2.bind(this)}
            />
            </div>
          )
        }
    }
    
    function parent(props){
      let 通信1 = props.通信函数1
      let 通信2 = props.通信函数2
      return (
        <div class="playground">
          //parent再把通信函数传给div孙子级组件
           <Track1 通信={通信1} />
           <Track2 通信={通信2}/>
        </div>
      )
    }
    
    div孙子级组件会调用通信函数
    
    //这个div1是孙子组件
    class div1 extends React.Component{
        ....
        this.state.通信()
    }
    //这个div2也是孙子元素
    class div2 extends React.Component{
       ....
      this.state.通信2()
    }
    
    • 类似父子关系组件之间的通信就是这样一次传给函数,最后子级调用这个函数的过程。

    4 . 任意组件之间通信

    • 发布订阅模式(EventHub)
    var eventHub = {
        //发布事件
        trigger(eventName,data){}, //参数一为事件名,参数二位要发布的数据
        //订阅事件
        on(eventName,function(){}) //参数一为事件名,参数二为调用函数
    }
    
    
    eventHub.on('事件名',function(){})//订阅,click是事件名称
    eventHub.trigger('事件名',data)
    
    • 单向数据流:
      原理:一个组件向下延申拥有树形关系的子组件,那么如何在互相没有直接关系 的组件之间通信呢?对此React提供了一种发布订阅模式(eventHub)的功能,eventHub 的具体用法在上一内容中有。只要其中一个组件给页面发布修改请求,这个请求就会被最订阅机质收到,这个机质是个对象,只存在内存中,不会被渲染到页面中,订阅机制收到后给最高级的组件传递信息,然后由父向子级组件依次通过props传递调用函数最后被各个子组件调用,最后进行(DOM diff) 渲染。这样就可以在任意组件之间进行通信了。

    • Redux
      使用eventHub发布订阅模式的特点是所有的动作都是通过事件来完成,数据必须放在顶层组件。

      • 下面是一些约定名词:
        • store 所有存数据的地方
        • store 对象中的对于数据的操作叫 reducer
        • eventHub.on 订阅subscribe
        • eventHub.trigger 发布action
        • eventHub.trigger('eventName',data) eventName叫action type 、data 叫 payload
    • Redux的优点:
      1. eventHub的所有动作都是通过事件来进行的,而且事件名可以是任意的,所以可能会存在隐藏的Bug,对此Redux做出了调整:

        switch (action.type) {
            case 'event1':
              function() { }
              break;
            case 'event2':
            function() { }
              break;
              ....
          default:
            return {
          
          }
        }
      

    就这样吧所有事件统一列在一个地方,防止重复使用

    1. Redux把所有数据写在顶层的组件中,并且只能只读取。
    2. 提高了前端的门槛,对于英语的要求较高。

    5. Readux

    • 使用Redux的步骤:
      1. 声明一个store,专门保存数据的,
        声明时必须使用createStore,接受的参数叫counter的一个函数
          counter(state, action) {return 新的数据} //参数一为初始数据,参数二为### 1. class组件
        

    复杂的组件,需要记录自己内部状态的话,使用class组件,因为function不能有局部变量和方法,而class可以有。

     //一部分页面标签放在一个函数里
    function App(){
      return (
        <div>
          app
        </div>
      )
    }
    //必须继承组件,添加extends React.Component
    class App2 extends React.Component{
    
      constructor(props){ //声明变量必须写在constructor里面
        super(props)//使用constructor必须写这个
        this.state= {  变量必须写在this.state里
           number:0
        }
      }
     
          
      add(){
        this.setState({
          number: this.state.number += 1
        })
      }
      render(){ //局部render
        return (
          <div>
            app 2 {this.props.name}
            <div>
              {this.state.number} 
              <button onClick={this.add.bind(this)}>+</button>
            </div>
          </div>
        )
      }
    }
    
    
    render()
    
    function render(){
      
      ReactDOM.render(
          <App2 name="qinglin" age="18"/>, 
          document.querySelector('#root'))
    }
    

    2. 函数组件

    把组成一部分页面的标签写在一个函数中,叫做函数组件。

    • 在上一节中说过React的作者的第一个创举,组件当中体现了第二个创举:标签的名字就是函数,标签的属性的key value 理解成一个对象,函数的参数就是这个对象。
      例如:
    let number = 0
    
    add =()=>{
      number += 1
      render()
    }
    
    minus =()=>{
      number -= 1
      render()
    }
     
     //一部分页面标签放在一个函数里
    function App(){
      return (
        <div>
      //这里的Box1标签就是函数,代表页面一部分的标签,标签的属性其实是对象,下面两个函数的参数obj就是这个对象
          <Box1 name="加一" />
        </div>
      )
    }
    
    function Box1(obj){
      return (
        <div class="parent">
        我的名字是{obj.name}
        <hr />
          <span>{number}</span>
          <button onClick={add}>+</button>
          <button onClick={minus}>-</button>
        </div>
      )
    }
    
    
    render()
    
    function render(){
      
      ReactDOM.render(
          //虚拟DOM,本质就是对象
          
          
          <App/>, //这是XML语法
          
          
          document.querySelector('#root'))
    }
    
    
    
    
    

    【涉及到的知识点】

    • this.setState ————

      • 优点:回对更新优化,会把多次更新结果只进行一次渲染就能完成
      • 缺点:同时带来了弊端,有时候会有多个执行语句时异步更新
    • DOM diff ——— react每次修改变量都会自动智能地去局部更新页面内,更新之前都会把最新信息跟之前相比较,然后只更新有变化的部分,这种非常友好的过程叫DOM diff。


    3. 组件通信

    3.1 父子通信
    • 子组件向父级组件传递信息:
      原理:父级组件传一个函数,子元素在必要时(回调)调用通信函数(通信函数被调用时还可以传给它一些参数页面中可以渲染出来)。
       //代码示例
    这个App是父元素
    class App extends React.Component{ 
        constructor(){
           this.state={
              ...
          }
          this.setState({
            ....
          })
        }
    
        通信函数1(){}
        通信函数2(){}
        //App父级组件会把两个通信函数分别传给子级组件div1 和 div2
        render(){
          return (
            <div>
              <div1 f1 = {this.通信函数1.bind(this)}></div1>
              <div1 f2 = {this.通信函数2.bind(this)}></div1>
            </div>
          )
        }
    }
    
    //两个div子组件会调用通信函数
    
    //这个div1是子元素
    class div1 extends React.Component{
        ....
        this.state.通信函数1()
    }
    //这个div2也是子元素
    class div2 extends React.Component{
       ....
      this.state.通信函数2()
    }
    
    • 父级组件向子级组件传递信息:
      父级组件通过 props 给子组件的某个属性传一个值
        function App(){
            return (
                  <div>
                       <span message="你好!"/>
                  </div>
            )
        }
        
      function span(props){
          return (
            <p>子级组件得到的信息是:{props.message}</p>
          )
       }
      
      ReactDOM.renfer(
         <App />,
         document.querySelector("root")   
      )
      

    3.1 爷孙通信

    原理:爷爷级组件把一个或多个函数传给父级组件,父级组件再把这个函数透传给子级组件,最后自己组建调用这个函数。

    代码示例,
    这个App是父元素
    class App extends React.Component{ 
        constructor(){
           this.state={
              ...
          }
          this.setState({
            ....
          })
        }
    
        通信函数1(){}
        通信函数2(){}
        //App爷爷级组件会把两个通信函数分别传给父级组件parent
        render(){
          return (
            <div>
              <parent  
                      success1={this.success1.bind(this)}
                       success2={this.success2.bind(this)}
            />
            </div>
          )
        }
    }
    
    function parent(props){
      let 通信1 = props.通信函数1
      let 通信2 = props.通信函数2
      return (
        <div class="playground">
          //parent再把通信函数传给div孙子级组件
           <Track1 通信={通信1} />
           <Track2 通信={通信2}/>
        </div>
      )
    }
    
    div孙子级组件会调用通信函数
    
    //这个div1是孙子组件
    class div1 extends React.Component{
        ....
        this.state.通信()
    }
    //这个div2也是孙子元素
    class div2 extends React.Component{
       ....
      this.state.通信2()
    }
    
    • 类似父子关系组件之间的通信就是这样一次传给函数,最后子级调用这个函数的过程。

    4 . 任意组件之间通信

    • 发布订阅模式(EventHub)
    var eventHub = {
        //发布事件
        trigger(eventName,data){}, //参数一为事件名,参数二位要发布的数据
        //订阅事件
        on(eventName,function(){}) //参数一为事件名,参数二为调用函数
    }
    
    
    eventHub.on('事件名',function(){})//订阅,click是事件名称
    eventHub.trigger('事件名',data)
    
    • 单向数据流:
      原理:一个组件向下延申拥有树形关系的子组件,那么如何在互相没有直接关系 的组件之间通信呢?对此React提供了一种发布订阅模式(eventHub)的功能,eventHub 的具体用法在上一内容中有。只要其中一个组件给页面发布修改请求,这个请求就会被最订阅机质收到,这个机质是个对象,只存在内存中,不会被渲染到页面中,订阅机制收到后给最高级的组件传递信息,然后由父向子级组件依次通过props传递调用函数最后被各个子组件调用,最后进行(DOM diff) 渲染。这样就可以在任意组件之间进行通信了。

    • Redux
      使用eventHub发布订阅模式的特点是所有的动作都是通过事件来完成,数据必须放在顶层组件。

      • 下面是一些约定名词:
        • store 所有存数据的地方
        • store 对象中的对于数据的操作叫 reducer
        • eventHub.on 订阅subscribe
        • eventHub.trigger 发布action
        • eventHub.trigger('eventName',data) eventName叫action type 、data 叫 payload
    • Redux的优点:
      1. eventHub的所有动作都是通过事件来进行的,而且事件名可以是任意的,所以可能会存在隐藏的Bug,对此Redux做出了调整:

        switch (action.type) {
            case 'event1':
              function() { }
              break;
            case 'event2':
            function() { }
              break;
              ....
          default:
            return {
          
          }
        }
      

    就这样吧所有事件统一列在一个地方,防止重复使用

    1. Redux把所有数据写在顶层的组件中,并且只能只读取。
    2. 提高了前端的门槛,对于英语的要求较高。

    5. VanillaJs

    • 使用Redux之关键函数:
      声明一个store,专门保存数据的,
      声明时必须使用createStore,接受的参数叫counter的一个函数

          ```
           counter(state, action) {return 新的数据} //这个函数提前声明,函数的参数一为初始数据,      
          参数二为操作数据的函数
           var store = Redux.createStore(counter)   //接受一个函数为参数
         ```
      
    • 使用redux的思路:

      1. dispatch一个action
      2. counter函数生成一个新的state,然后触发一个事件
      3. 上一步出触发的事件被subscribe函数接受,
      4. subscribe函数会调用render函数,然后重新render
      5. 第二次render之后在得到新的store,浏览器DOM diff 之后渲染页面

    6. Redux

    • react比vanilla好的地方是会DOM diff,局部更新。

    7. React-Redux

    7.1 API
    • connect(mapStateToProps,mapDispatchToProps)(App)
      一个括号为一个参数,第一个括号里可有多个参数,第二个括号为第二个参数 ;功能是把数据、数据变更动作、组件组合起来。
    • Provider() 从React-Redux引入之后以标签的形式写成包围组件,功能是获取state,然后通知到里面的每一个组件

    • 写这一节博客,做了简单的项目[https://github.com/cnqinglin/react-redux-v1]之后的最大的感觉就是React社区的东西其实不难,但为什么总感觉很难是因为它给就概念都给了一个新的名字。

    相关文章

      网友评论

        本文标题:【React】组件

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