像学vue一样学习react,系列二(react组件)

359 阅读2分钟

组件的定义

  • 函数式组件一般使用于静态组件,不包含点击等事件
  • 类组件使用于事件比较多的情况下
import React from 'react'
//函数式组件
function FnComponent(props) {
  console.log(props)//这里是父组件传的参数
  return (
    <div className='panel'>
      <h1>我是函数式组件</h1>
    </div>
  )
}
//类组件,需要继承react的component
class ClassComponent extends React.Component {
  render() {
    console.log(this.props) //这里会接收父组件的参数
    return (
      <div className='panel'>
        我是类组件
      </div>
    )
  }
}

组件之间的交互

组件传参 (父->子)

可以看到跟vue很像,都是利用props, vue借鉴了react
vue一样,单向流通,不能子传父

  • 父组件father.js
import React from 'react'
import './study.scss'

import Child from './child'

export default class Father extends React.Component{
  render() {
    const fatherValue = '我是父组件的值'
    return (
      <div className={'father'+' '+'panel'}>
        <h2>我是father父组件</h2>
        {/*子组件child, 传参对象fatherValue*/}
        <Child fatherValue={fatherValue}/>
      </div>
    )
  }
}
  • 子组件child.js
import React from 'react'
import './study.scss'

export default class Child extends React.Component{
  render() {
    console.log(this.props.fatherValue)//从父组件接收的值,输出 ‘我是父组件的值’
    return (
      <div className={'child'+' '+'panel'}>
        <h2>我是child子组件</h2>
      </div>
    )
  }
}

组件传参 (子->父)

父组件利用Props传递给子组件一个方法, 子组件通过这个方法把值传递回去

  • 父组件father.js
import React from 'react'
import './study.scss'

import Child from './child'

export default class Father extends React.Component{
  constructor(props) {
    super(props)
  }
  render() {
    const fatherValue = '我是父组件的值'
    return (
      <div className={'father panel'}>
        <h2>我是father父组件</h2>
        {/*子组件child*/}
        <Child 
            fatherValue={fatherValue} 
            getChildDataFn={this.getChildDataFn}
        />
      </div>
    )
  }
  getChildDataFn(val) {
    console.log('父组件接收的值', val)
  }

}
  • 子组件child.js
import React from 'react'
import './study.scss'

export default class Child extends React.Component{
  render() {
    console.log(this.props.fatherValue)//从父组件接收的值,输出 ‘我是父组件的值’
    return (
      <div className={'child panel'}>
        <h2>我是child子组件</h2>
        <button onClick={()=>this.sendDataByChild()}>点击传递值给父元素</button>
      </div>
    )
  }
  sendDataByChild() {
    this.props.getChildDataFn('我侄子组件的值')
  }
}

效果, 子组件点击后向父组件传递值

xF0k70vmCQ.gif

父组件方法触发子组件方法

归根结底还是父组件来操作
父组件传方法到子组件, 子组件把自己对象推给父组件, 父组件使用子组件对象来操作子组件方法

  • 父组件father.js
render() {
 return (
     <button onClick={()=>this.triggerChildFn()}>触发子组件方法</button>
     <Child
      onRef = {this.onRef.bind(this)}
    />
 )
}
onRef(ref) {
  console.log(31, ref)
  this.child = ref //父组件的child属性上 绑定子组件
}
triggerChildFn(e) {
  console.log(35, this.child)
  this.child.childFn() //触发子组件方法
}
  • 子组件child.js

接收到父组件的onRef方法, 然后把this返回到父组件

componentDidMount() {
  console.log(21, this)
  this.props.onRef(this)
}

总结

其实react只有父传子,都是通过父组件来操作的
还有,写的时候要注意this的指向,他不是默认指向组件的

组件的事件

这里要弄懂this在es6和es5内的关系。。掘金上有很多介绍this的。

  • 点击拿值,建议使用es6的箭头函数写法,es5,function需要使用bind函数
render() {
  return (
    <div className={'panel'}>
      <h2>事件传值</h2>
      <div className={'item-border'}
           onClick={(e)=>this.clickHasVal('test', e)}>
        点我拿值
      </div>
    </div>
  )
}
clickHasVal = (val, e)=>{
  console.log(val, e.target)
}

react阻止冒泡用原生的就行,vue中需要使用事件修饰符 e.stopPropagation()