zoukankan      html  css  js  c++  java
  • react02

    组件传值:

      父传子:

        传递:给子组件标签上绑定一个自定义属性,值为需要传递的数据

            <One username={this.state.name}></One>

        接收:在子组件render函数中通过props接收

            let { username } = this.props

      * react中如何限制传递来的数据类型和设置初始值:

        ①下载插件:npm i prop-types      从v15.5开始,React.PropTypes助手函数被弃用,使用 prop-types 库来定义 contextTypes

        ②在子组件中引入:import PropTypes from 'prop-types'

        ③对当前组件进行类型限制和默认值的设置

            // propTypes是组件上的属性,PropTypes是数据类型检测
            Two.propTypes = {
              name: PropTypes.string
            }
    
            Two.defaultProps = {
              name: '吴小明'
            }

      * vue中是怎样限制类型和设置初始值的:

        

      子传父:

        传递:在子组件中通过 this.props.事件函数 来进行传值

            <button onClick={this.handleAdd.bind(this)}>点击发送给父组件</button>

    handleAdd() { this.props.toApp('我是从two组件传来的') }

        接收:在子组件标签上绑定一个自定义属性,值为需要接收参数的函数

            <Two toApp={this.handle2.bind(this)}></Two>
    
    
            handle2(value) {
              this.setState({
                towValue: value
              })
            }    

       非父子:

        1、通过onserver传值

          ①定义observer.js

    const eventList = {}
    
    const $on = function(eventName, callback) {
      if (!eventList[eventName]) {
        eventList[eventName] = []
      }
    
      eventList[eventName].push(callback)
    }
    
    const $emit = function(eventName, params) {
      if (eventList[eventName]) {
        var arr = eventList[eventName]
        arr.forEach((cb) => {
          cb(params)
        })
      }
    }
    
    const $off = function(eventName, callback) {
      if (eventList[eventName]) {
        if (callback) {
          var index = eventList[eventName].indexOf(callback)
          eventList[eventName].splice(index, 1)
        } else {
          eventList[eventName].length = 0
        }
      }
    }
    
    export default {
      $on,
      $emit,
      $off
    }
    View Code

          ②在需要传递的组件中引入observer.js

            import Observer from '../observer'

          通过Observer.$emit()传值:

            <button onClick={this.handleClick.bind(this,'传个值给Two组件')}>传个值给Two组件</button>
             handleClick(value){
               Observer.$emit('abcd',value)
             }

          ③在需要接收的组件中引入observer.js

            import Observer from '../observer'

          通过Observer.$on()接收值

                constructor() {
                  super()
                  this.state = {
                    value: ''
                  }
                  Observer.$on('abcd', (value) => {
                    this.setState({
                      value
                    })
                  })
                }

        2、通过context传值

          vue中:provide/inject

          react中:通过context创建一个生产者,再创建一个消费者供组件使用。其中生产者是父级,消费者是子级。

          实践step:

            ①创建createContext.js文件

              import React, { createContext } from 'react'
    
              export let { Provider, Consumer } = createContext() // Provider生产者,Consumer消费者

            ②在父级中引入Provider并将当前根节点包裹,Provider标签中value属性中是一个对象,用于传值

                 import { Provider } from './createContext'
    
                      render() {
                        return (
                          // Provider包裹所有的子级
                          <Provider
                            value={{
                              name: '孙艺珍',
                              age: 18
                            }}
                          >
                            <div className="app">
                              <One></One>
                            </div>
                          </Provider>
                        )
                      }            

            ③在自己中引入Consumer并将当前根节点包裹,Consumer中是一个函数返回一个jsx

               import { Consumer } from '../createContext'
    
                      render() {
                        return (
                          // Consumer包裹的组件接收Provider传来的值,Consumer中是一个函数返回一个jsx语法
                          <Consumer>
                            {(props) => {
                              let { name, age } = props
                              return (
                                <div className="Two">
                                  <h1>Two组件</h1>
                                  接收到来自Provider传来的name为:{name},age为:{age}
                                  <Three></Three>
                                </div>
                              )
                            }}
                          </Consumer>
                        )
                      }

          利用高阶组件对Consumer进行二次封装:

            ①src下创建connect/createContext.js

              import React, { createContext } from 'react'
    
              export let { Provider, Consumer } = createContext()

            ②src下创建高阶组件:hoc/connect.js 用于封装Consumer

                    import React from 'react'
                    import { Consumer } from '../connect/createContext'
    
                    export const connect = (WrapperComponent) => {
                      return class extends React.Component {
                        render() {
                          return (
                            <Consumer>
                              {(props) => {
                                return <WrapperComponent {...props}></WrapperComponent>
                              }}
                            </Consumer>
                          )
                        }
                      }
                    }

            ③在父组件中通过Provider传值

                    import React, { Component } from 'react'
                    import Two from './two'
                    import { Provider } from '../connect/createContext'
    
                    class One extends Component {
                      render() {
                        return (
                          <Provider value={{ name: '孙艺珍', sex: '女' }}>
                            <div className="One">
                              <h1>One组件</h1>
                              <Two></Two>
                            </div>
                          </Provider>
                        )
                      }
                    }
    
                    export default One

            如果用原来的Consumer接收:

                    import React, { Component } from 'react'
                    import Three from './three'
                    import { Consumer } from '../connect/createContext'
    
                    class Two extends Component {
                      render() {
                        return (
                          <Consumer>
                            {(props) => {
                              let { name, sex } = props
                              return (
                                <div className="Two">
                                  <h1>Two组件</h1>
                                  姓名:{name},性别:{sex}
                                  <Three></Three>
                                </div>
                              )
                            }}
                          </Consumer>
                        )
                      }
                    }
    
                    export default Two

            ④用封装好的Consumer接收:

                    import React, { Component } from 'react'
                    import { connect } from '../hoc/connect'
    
                    class Three extends Component {
                      render() {
                        let { name, sex } = this.props
                        return (
                          <div className="Three">
                            <h1>Three组件</h1>
                            姓名:{name},性别:{sex}
                          </div>
                        )
                      }
                    }
    
                    export default connect(Three)

            

        3、redux:公共状态管理

    组件分类:

      1、类组件 - class App extends React.Component {render (){}}

      2、函数组件 - function fn (){return (<div>我是一个函数组件</div>)}

      3、ui组件

      4、容器组件

      5、高阶组件

      6、受控组件 - input加上value属性和onChange事件后变为受控组件

      7、非受控组件 - input加上defaultValue依旧可以输入内容,此时为非受控组件

      react中函数组件和类组件的区别:

        函数组件:相比较类组件来说比较轻便、速度较快(16.8中引入hooks来解决函数组件的这个问题)

        类组件:有属于自己的生命周期,可以在指定的时间做指定的事,可以存储属于自己的状态

      高阶组件:

        高阶组件是一个函数,它接收一个组件返回一个相对增强性的组件,简称HOC

    react中的插槽:

      只需在子组件中通过 this.props.children 进行嵌套的内容。

      1、子组件标签中的内容默认是不显示的:

        import React from 'react'
        import Header from './Header'
        class App extends React.Component {
          render() {
            return (
              <div className="app">
                <Header>
                  <h2>标题</h2>
                </Header>
              </div>
            )
          }
        }
    
        export default App

      2、子组件中通过 this.props.children 接收

        import React from 'react'
        import './index.css'
    
        class Header extends React.Component {
          render() {
            return <div className="header">{this.props.children}</div>
          }
        }
    
        export default Header

    生命周期:

      1、constructor:

        1、当前生命周期是组件在初始化的时候执行的,在constructor中必须要写super()否则this的指向会发生错误

        2、可以在当前生命周期中存放当前组件所需的一些状态,这些状态必须要放到this.state中

        3、在当前生命周期中访问不到this.props,如果要访问this.props必须要在constructor中传入props

            constructor(props) {
              super(props)
              this.state = {
                msg: '孙艺珍'
              }
              console.log('constructor', props,this.props) // 在super中传入props才可以用this.props接收到数据
            }

      2、componentWillMount:

        1、当前生命周期是组件挂载前。此时数据和模板还未结合,因此可以在当前生命周期中做数据最后的更改

        2、当前生命周期中可以接收到外部的数据,可以访问到this.props

        3、在v17.0中被废除,使用时页面会报警告

        

      3、render:(多次执行)

        1、当前生命周期是一个渲染函数,是数据和模板相结合的一个函数。当前生命周期在执行的时候会将渲染好的模板在缓存中存储一份,这就是diff算法比较(diff算法:新旧两个虚拟DOM的对比)

        2、当前生命周期会多次执行,当this.setState()或者this.props发生改变的时候就会执行

        3、可以通过控制shouldComponentUpdate来减少render函数渲染的次数来优化性能

      4、componentDidMount:

        1、当前生命周期是数据和模板已经结合完毕并且挂载到页面上,因此我们可以在当前生命周期中获取到真实的DOM结构

        2、通常会在当前生命周期中进行前后端数据的交互和方法的实例化(swiper)

        react中如何访问到DOM节点:

          第一种:<h2 ref='h2'></h2>

              this.refs.h2

          第二种:<h2 ref={(h2)=>{this.h2=h2}}></h2>

              this.h2

            render() {
              return (
                <div>
                  <h1>One组件</h1>
                  <h2 ref="h2">h2标签</h2>
                  <h3 ref={(h3) => (this.h3 = h3)}>h3标签</h3>
                </div>
              )
            }
            componentDidMount() {
              console.log('挂载后', this.refs.h2,this.h3) // <h2>h2标签</h2> <h3>h3标签</h3>
            }

      5、componentWillReceiveProps:(多次执行)

        1、当props的数据发生改变的时候会执行当前生命周期,在当前生命周期函数中有个参数,该参数是新的props

        2、当前生命周期在v17.x的版本中被废除

      6、shouldComponentUpdate:(多次执行)

        1、当前生命周期书写的时候必须return一个布尔值,当值为true时继续执行下面的生命周期;如果为false不执行下面的生命周期

        2、当前生命周期中有2个参数,一个是新的props,一个是新的state,可以根据新的props/state与旧的props/state比较减少render函数的渲染次数

        3、当前生命周期决定render函数是否渲染,而不是决定数据是否更新

            shouldComponentUpdate(newProps, newState) {
              console.log('决定数据是否更新', newProps, newState)
              if (this.state.msg === newState.msg) {
                return false
              } else {
                return true
              }
            }

      7、componentWillUpdate:(多次执行)

        1、当前生命周期在数据更新时执行,有2个参数,一个是新的props,一个是新的state

        2、可以在当前生命周期中对数据进行最后的更改

        注意:

          1、尽量不要在当前生命周期中调用this.setState(),死循环

          2、当前生命周期在v17.0中被废除

      8、componentDidUpdate:(多次执行)

        1、当前生命周期在数据更新完后执行,可以在这里获取到数据更新后最新的DOM结构(一定要加边界条件)

        2、当前生命周期中有2个参数,一个是旧的props,一个是旧的state

      9、componentWillUnmount:

        当前生命周期在组件被卸载时执行,可以在当前生命周期做性能的优化:事件的解绑、定时器的移除……

    react中如何强制更新数据:

      this.forceUpdate()

      注:vue中通过this.$forceUpdate()

    常见的生命周期面试题:

      1、react中哪些生命周期会执行一次,哪些会执行多次

        执行一次:

          constructor

          componentWillMount

          componentDidMount

          componentWillUnmount

        执行多次:

          componentWillReceiveProps

          shouldComponentUpdate

          componentWillUpdate

          render

          componentDidUpdate

      2、react中第一次执行的生命周期有哪些

        constructor

        componentWillMount

        render

        componentDidMount

      3、render什么时候被触发

        当this.props或this.setState()发生改变的时候触发

      4、谈谈对shouldComponentUpdate的理解

      5、当this.props或this.setState()执行的时候会触发哪些生命周期

        this.props:

          componentWillReceiveProps

          shouldComponentUpdate

          componentWillUpdate

          render

          componentDidUpdate

        this.setState():

          shouldComponentUpdate

          componentWillUpdate

          render

          componentDidUpdate

    css in js:styled-components  将css组件化

      安装插件:npm install styled-components

      新建styled.js:

        import styled, { keyframes } from 'styled-components'
        import logo from '../../logo.png' // 图片的引入
    
        // 定义动画
        const move = keyframes`
          0%{
            transform:rotate(0deg);
          }
          100%{
            transform:rotate(360deg);
          }
        `
        export const HeaderContainer = styled.div`
           100%;
          height: 1rem;
          background-color: ${(props) => props.color}; /* 可以传参 */
          color: #fff;
          display: flex;
          justify-content: center;
          align-items: center;
          /* 像sass和less一样嵌套 */
          button {
            background-color: yellow;
            border: 0;
            animation: ${move} 3s 1s;
          }
          button.a {
            background-color: #c33;
          }
        `
        // 可以接收父组件传来的值渲染
        export const SerachInput = styled.input.attrs((props) => ({
          type: props.type,
          value: props.value
        }))`
           60%;
          height: 0.5rem;
          border: 0;
          border-bottom: 1px solid #ccc;
          background-image: url(${logo}); /* 图片的使用 */
          background-repeat: no-repeat;
          background-size: 100% 100%;
        `
        export const MyButton = styled.button`
           100px;
          height: 40px;
          text-align: center;
          line-height: 40px;
          color: black;
          background-color: yellow;
          border: 0;
          animation: ${move} 3s 1s;
        `
        // 继承
        export const ChildrenButton = styled(MyButton)`
          background-color: green;
        `

      index.jsx中引入和使用:

        import React, { Component } from 'react'
        import {
          HeaderContainer,
          SerachInput,
          MyButton,
          ChildrenButton
        } from './styled'
    
        class Header extends Component {
          constructor() {
            super()
            this.state = {
              inputVal: '请输入'
            }
          }
          render() {
            return (
              <div>
                <HeaderContainer color="deeppink">
                  猫眼电影
                  <SerachInput
                    type="text"
                    value={this.state.inputVal}
                    onChange={this.onChange.bind(this)}
                  ></SerachInput>
                  {/* <MyButton>按钮</MyButton>
                  <ChildrenButton>子按钮</ChildrenButton> */}
                  <button>按钮</button>
                  <button className="a">按钮</button>
                </HeaderContainer>
              </div>
            )
          }
          onChange() {}
        }
    
        export default Header
  • 相关阅读:
    PHP登入
    PHP注册
    PHP数据访问
    php实现人员的权限管理
    PHP实现简单的评论与回复功能还有删除信息
    php文件的管理
    文件的操作
    文件上传及预览
    ajax分页
    三级联动
  • 原文地址:https://www.cnblogs.com/wuqilang/p/14267384.html
Copyright © 2011-2022 走看看