React基础二-m

复习

  • 构造函数: https://blog.csdn.net/weixin_41796631/article/details/82939585
  • 解构赋值: https://www.jianshu.com/p/d4a3baeac680
  • 箭头函数
  • this
  • 事件

状态的修改

构造函数的解释:contructor的理解

  1. 这里的props参数是什么?

​ ! props就是父组件绑定在子组件身上的属性

  1. 这里super( props ) 做了什么?

​ ! 继承, 它将 props 属性赋值给 this.props

  • 状态修改

    • 事件:事件源,事件类型,事件处理程序( 1. 事件处理程序我们是直接定义为实例方法

        2. 事件处理程序我们建议写成箭头函数 - this指向不改变)
      
    • 修改状态

    1. 在React中状态的修改只能使用setState()
    2. setState() 的作用是用来更新视图的
    3. setState是异步的
    4. setState( obj/function, callback ) 参数是有两个的
      • 第一个参数是用来修改状态的,可以是Object/function
        • function必须要有返回值
      • 第二个参数是一个回调函数,可以说是一个由数据改变而引起的副作用执行
    5. React中为一个可以更新视图的就是setState
    • 示例一

      import React, { Component } from 'react'
      
      export default class StateComp extends Component {
      
        constructor(props) {
          super(props)
          this.state = {
             info: 'React是前端流行的三大框架之一'
          }
        }
        
        // state = {
        //   info: 'Hello React'
        // }
      
        changeState = () => {
      
        /* ! 参数是对象
          this.setState({
            info: '千锋教育'
          }) 
        */
      
        // 参数是方法 - 方法时必须要有返回值的,返回值是对象
      
          this.setState(() => {
            console.log( 1 )
            return {
              info: '前端无情'
            }
          },() => {
            console.log( 2 )
            document.querySelector('span').style.background = 'red'
          })
      
          console.log( 3 )
      
        }
      
        render() {
          return (
            <div>
              <button onClick = { this.changeState } > change state  </button>
              <p>state的定义 { this.state.info } </p>
              <span> info变化了 </span>
            </div>
          )
        }
      }
      
    • 示例二

      import React, { Component } from 'react'
      
      export default class StateDemo extends Component {
        constructor(props) {
          super(props)
        
          this.state = {
             arr: [ 1, 2,3 ]
          }
        }
      
        addItem = () => {
          //修改状态了
          this.setState(() => {
            this.state.arr.push( 4 ) 
            return {
              arr: this.state.arr
            }
          })
        }
        
        render() {
          const { arr } = this.state 
          return (
            <div>
              <button onClick = { this.addItem }> + 4 </button>
              <ul>
                {
                  arr.map( (item,index) => <li key = { index } > { item } </li>)
                }
              </ul>
            </div>
          )
        }
      }
      
      

属性与状态

数据最好是由外传到内–多用props

相似点:都是纯js对象,都会触发render更新,都具有确定性(状态/属性相同,结果相同)

不同点:

  1. 属性能从父组件获取,状态不能
  2. 属性可以由父组件修改,状态不能
  3. 属性能在内部设置默认值,状态也可以
  4. 属性不在组件内部修改,状态要改 【 属性只能外部修改,内部不允许修改】
  5. 属性能设置子组件初始值,状态不可以
  6. 属性可以修改子组件的值,状态不可以

state 的主要作用是用于组件保存、控制、修改自己的可变状态state 在组件内部初始化,可以被组件自身修改,而外部不能访问也不能修改。你可以认为 state 是一个局部的、只能被组件自身控制的数据源。state 中状态可以通过 this.setState方法进行更新,setState 会导致组件的重新渲染。

**props 的主要作用是让使用该组件的父组件可以传入参数来配置该组件**。它是外部传进来的配置参数,组件内部无法控制也无法修改。除非外部组件主动传入新的 props,否则组件的 props 永远保持不变。

如果搞不清 stateprops 的使用场景,记住一个简单的规则:尽量少地用 state,多用 props

没有 state 的组件叫无状态组件(stateless component),设置了 state 的叫做有状态组件(stateful component)。因为状态会带来管理的复杂性,我们尽量多地写无状态组件,尽量少地写有状态的组件。这样会降低代码维护的难度,也会在一定程度上增强组件的可复用性。

无状态组件也就是函数式组件

有状态组件就是类组件

经验:

​ 功能复杂,我们使用类组件

​ 功能单一,我们使用函数式组件

组件props要想变,那么就外部修改

组件state要想变,那么组件内部自身通过setState修改

react性能优化一个方案: 就是多使用无状态组件( 函数式组件 )

状态提升

  • 如果有多个组件共享一个数据,把这个数据放到共同的父级组件中来管理

受控与非受控组件

  • React组件的数据渲染是否被调用 是通过 传递过来的props完全控制,控制则为受控组件,否则非受控组件。

  • 示例:

    Father.js
    
    import React, { Component } from 'react'
    import ControlledComp from './ControlledComp';
    import UnControlledComp from './UnControlledComp';
    
    export default class Father extends Component {
        constructor(props) {
            super(props)
        
            this.state = {
                 flag : true,
                 money:100
            }
        }
        changeFlag = () => {
            this.setState({
                flag:!this.state.flag
            })
        }
        
        render() {
            const {flag} = this.state
            const {money } = this.state
            return (
                <div>
                   <button onClick = {this.changeFlag}>change flag</button> 
                   <ControlledComp flag = { flag }/>
                   <UnControlledComp money = {money}/>
                </div>
            )
        }
    }
    
    
    //受控组件
    
    import React, { Component } from 'react'
    
    export default class ControlledComp extends Component {
        
        render() {
            const { flag } = this.props
            return (
                <div>
                    <p> {flag ? '❤️取消' : '🖤收藏'}</p>
                    <p> {flag && '❤️取消' || '🖤收藏'}</p>
                </div>
            )
        }
    }
    
    
    //非受控组件
    
    import React, { Component } from 'react'
    
    export default class UnControlledComp extends Component {
        render() {
            const { money } = this.props
            return (
                <div>
                    <p> 给了我 { money } </p>
                </div>
            )
        }
    }
    
    

渲染数据

  • 条件渲染

     <p> {flag ? '❤️取消' : '🖤收藏'}</p>
     <p> {flag && '❤️取消' || '🖤收藏'}</p>
    
  • 列表渲染

    
    import React,{Component} from 'react'
    
    export default class ListComp extends Component{
        constructor(props){
            super(props)
            this.state = {
                list:[
                    {
                        id: 1,
                        shop_name: '汽车'
                      },
                      {
                        id: 2,
                        shop_name: '衣服'
                      }
                ]
            }
        }
    
        renderItem = () =>{
            const { list } = this.state
            return list.map(item => <li key = {item.id}>{item.shop_name}</li>)
        }
    
        render(){
            
            return(
                <div>
                    <ul>
                        {
                            this.renderItem()
                        }
                    </ul>
                </div>
            )
        }
    }
    

事件处理

绑定事件

  • 采用on+事件名的方式来绑定一个事件,注意,这里和原生的事件是有区别的,原生的事件全是小写onclick, React里的事件是驼峰onClickReact的事件并不是原生事件,而是合成事件

事件handler的写法 (4种)

  • 直接在render里写行内的箭头函数(不推荐)

    • 示例:
    import React, { Component } from 'react'
    
    export default class EventOneComp extends Component {
      render() {
        return (
          <div>
            <button onClick = {() => { alert( 1 ) }}> render中直接写箭头函数 </button>
          </div>
        )
      }
    }
    
    
  • 在组件内使用箭头函数定义一个方法(推荐)

    • 示例:

      import React, { Component } from 'react'
      
      export default class EventTwoComp extends Component {
      
        constructor(props) {
          super(props)
        
          this.state = {
             money: '10000'
          }
        }
      
        changeMoney = () => {
          this.setState({
            money: '15000'
          })
        }
        
      
        render() {
          const { money } = this.state
          return (
            <div>
              <button onClick = { this.changeMoney }> change Money </button>
              <p> { money } </p>
            </div>
          )
        }
      }
      
      
  • 直接在组件内定义一个非箭头函数的方法,然后在render里直接使用onClick={this.handleClick.bind(this)}(不推荐)

    • 示例:

      import React, { Component } from 'react'
      
      export default class EventThirdComp extends Component {
        constructor(props) {
          super(props)
        
          this.state = {
             money: 15000
          }
        }
      
        changeMoney () {
          this.setState({
            money: 20000
          })
        }
        
      
        render() {
          const { money } = this.state
          return (
            <div>
              <button onClick = { this.changeMoney.bind( this ) }> change Money2 </button>
              <p> { money } </p>
            </div>
          )
        }
      }
      
      
  • 直接在组件内定义一个非箭头函数的方法,然后在constructor里bind(this)(推荐)

    • 示例:

      import React, { Component } from 'react'
      
      export default class EventFourComp extends Component {
      
        constructor(props) {
          super(props)
        
          this.state = {
             flag: true
          }
          this.changeFlag = this.changeFlag.bind( this )
        }
      
        changeFlag () {
          this.setState({
            flag: !this.state.flag
          })
        }
        
      
        render() {
          const { flag } = this.state
          return (
            <div>
              <button onClick = { this.changeFlag }> change flag </button>
              <p> { flag ? '❤️取消' : '🖤收藏' } </p>
            </div>
          )
        }
      }
      
      
  • 注意: 事件不能定义在函数式组件中

Event对象

  • 和普通浏览器一样,事件handler会被自动传入一个 event 对象,这个对象和普通的浏览器 event 对象所包含的方法和属性都基本一致。不同的是 React中的 event 对象并不是浏览器提供的,而是它自己内部所构建的。它同样具有event.stopPropagationevent.preventDefault 这种常用的方法
  • 事件对象中的值很多都是null,但是可以正常使用
  • e.target

事件参数的传递

  • render里调用方法的地方外面包一层箭头函数

    • 示例:

      import React, { Component } from 'react'
      
      

    export default class EventArguOneComp extends Component {
    constructor(props) {
    super(props)

      this.state = {
         money: 0
      }
    }
      
    changeMoney = ( val ) => {
      this.setState({
        money: val 
      })
    }
    
    render() {
      const { money } = this.state 
      return (
        <div>
          <button onClick = {() => { this.changeMoney( 100 ) }}> change money </button>
          <p> money有:{ money } </p>
        </div>
      )
    }
    

    }

    
    
    
  • render里通过this.handleEvent.bind(this, 参数)这样的方式来传递

    • 示例:

      import React, { Component } from 'react'
      
      export default class EventArguTwoComp extends Component {
      
        constructor(props) {
          super(props)
        
          this.state = {
             money: 0
          }
        }
      
        changeMoney ( val ) {
          this.setState({
            money: val
          })
        }
        
      
        render() {
          const { money } = this.state 
          return (
            <div>
                <button onClick = { this.changeMoney.bind( this, 10000 ) }> change money </button>
                <p> money有: { money } </p>
            </div>
          )
        }
      }
      
      
  • 通过event传递

  • 比较推荐的是做一个子组件, 在父组件中定义方法,通过props传递到子组件中,然后在子组件件通过this.props.method来调用

处理用户输入

  • import React, { Component } from 'react'
    
    export default class UserInputComp extends Component {
      constructor(props) {
        super(props)
      
        this.state = {
           firstName: '',
           lastName: ''
        }
      }
    
      getVal = ( e ) => {
        this.setState({
          [ e.target.name ]: e.target.value
        })
      }
      
    
      render() {
        const { firstName,lastName } = this.state 
        return (
          <div>
            姓: <input type = "text" name = "firstName" onChange = {  this.getVal }/> 
            <hr/>
            名: <input type = "text" name = "lastName" onChange = { this.getVal }/>
            <p> 欢迎:{ firstName } { lastName }  </p>
          </div>
        )
      }
    }
    
    
  • ref绑定

  • 建议不要过量使用ref , 会导致性能的浪费

​ 普通绑定

​ 函数形式 - 推荐

​ <input type=“text” ref = { el => this.user = el }/>

组件通信

父子组件通信

  • 无论父组件传递是props还是state,子组件都是通过props接收

  • 示例:

  • father
    import React, { Component } from 'react'
    import Son from './Son';
    
    export default class Father extends Component {
        constructor(){
            super()
            this.state = {
                money: 200
            }
        }
        render() {
            const { money } = this.state
            return (
                <div>
                    <Son money = {money}/>
                </div>
            )
        }
    }
    
    
    
  • son
    import React, { Component } from 'react'
    
    export default class Son extends Component {
        render() {
            const {money} = this.props
            return (
                <div>
                    <p> 爸爸给了:{money}</p>
                </div>
            )
        }
    }
    
    

子父组件通信

  • ​ 父组件传递方法给子组件,子组件调用父组件传递过来的方法

    ​ 注意: 自己的状态自己更改

  • 示例:

  • father
    import React, { Component } from 'react'
    import Son from './Son'
    
    export default class Father extends Component {
    
      constructor(props) {
        super(props)
      
        this.state = {
           money: 0
        }
      }
      
      handler = ( val ) => {
        this.setState({
          money: val 
        })
      }
    
      render() {
        const { money } = this.state 
        return (
          <div>
            <Son handler = { this.handler }/>
            <p> 儿子给了我 { money } </p>
          </div>
        )
      }
    }
    
    
  • son
    import React, { Component } from 'react'
    
    export default class Son extends Component {
    
      constructor(props) {
        super(props)
      
        this.state = {
           hongbao: 8000
        }
      }
      render() {
        const { handler } = this.props 
        const { hongbao } = this.state
        return (
          <div>
            <button onClick = {() => { handler( hongbao ) }}> git 老爸 红包  </button>
          </div>
        )
      }
    }
    
    

非父子组件通信

  • ref链

    1. ref = ‘xxx’ this.refs.xxx

    2. ref = { el => this.xxx = el } this.xxx 【 推荐

  • father
    import React, { Component } from 'react'
    import Son from './Son'
    import Girl from './Girl'
    
    export default class Father extends Component {
    
    
      kick = () => {
        this.son.changeFlag()
      }
    
      render() {
        return (
          <div>
            <Girl kick = { this.kick }/>
            <Son ref = { el => this.son = el }/>
          </div>
        )
      }
    }
    
    
  • import React, { Component } from 'react'
    
    export default class Girl extends Component {
      render() {
        const { kick } = this.props 
        return (
          <div>
             <button onClick = { kick }> 揍弟弟 </button>
          </div>
        )
      }
    }
    
    
  • son
    import React, { Component } from 'react'
    
    export default class Son extends Component {
        constructor(props) {
            super(props)
        
            this.state = {
                 flag:false
            }
        }
        changeFlag =()=>{
            this.setState({
                flag:true
            })
        }
    
        render() {
            const {flag} = this.state
            return (
                <div>
                    {
                        flag && <p> o(╥﹏╥)o</p>
                    }
                    
                </div>
            )
        }
    }
    
    

跨组件通信

​ context

​ 使用流程

​ - 创建上下文 React.createContext()

​ - 使用上下文包裹目标组件的父组件

    <MoneyContext.Provider value = { money }>
    	<Father></Father>
    </MoneyContext.Provider>

​ - 在目标组件中先定义一个静态属性 static contextType = MoneyContext

  • 通过 this.context来使用数据

  • import React, { Component,createContext } from 'react'
    
    // const MoneyContext = createContext( 默认值 )
    const MoneyContext = createContext( 0 )
    
    class Father extends Component{
      render () {
        return (
          <div>
            father
            <Son/>
          </div>
        )
      }
    }
    class Son extends Component{
    
      static contextType = MoneyContext
    
      render () {
        return (
          <div>
            son 
            <p> 爷爷给了我 { this.context } </p>
          </div>
        )
      }
    }
    
    export default class Stride extends Component {
      constructor(props) {
        super(props)
      
        this.state = {
           money: 100000
        }
      }
      
    
      render() {
        const { money } = this.state
        return (
          <div>
            <h3> 爷爷 </h3>
            <MoneyContext.Provider value = { money }>
              <Father/>
            </MoneyContext.Provider>
          </div>
        )
      }
    }
    
    
       - 
    

todolist案例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值