React脚手架+组件化开发+组件生命周期+组件通信

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

react脚手架create-react-app

1.作用 帮助我们生成一个通用的目录结构并且已经将我们所需的工程环境配置好
2.依赖环境
脚手架都是使用node编写的并且都是基于webpack的
3.安装node
4.安装脚手架

npm install -g create-react-app

5.检查脚手架版本

create-react-app --version

创建项目

create-react-app 项目名称

跑项目

yarn start

目录
在这里插入图片描述

React组件化开发

类组件
定义

  • 组件的名称是大写字符开头的无论类组件还是函数组件
  • 类组件需要继承自React.Component
  • 类组件必须实现render函数

使用class定义一个组件
constructor是可选的我们通常在constructor中初始化一些数据
this.state中维护的就是我们组件内部的数据
render()方法是class组件中

函数式组件

/**
 * 
 * 函数式组件的特点
 * 1.没有this对象
 * 2.没有内部的状态
 * 3.没有生命周期
 * 
 */
export default function App(){
  return (
    <div>我是function组件</div>
  )
}

类组件

import React, { Component } from "react";

export default class App extends Component {
  constructor() {
    super();

    this.state = {
      message: 'hello'
    }
  }
  render () {
    return (
      <div>
        <div>app组件</div>
        {/* alt+shift+f  代码格式化*/}
        <h2>{this.state.message}</h2>
      </div>
    )
  }
}

render函数的返回值

  • React元素通常通过JSX创建
  • 数组或fragments
  • portals可以渲染子节点到不同的DOM子树中
  • 字符串或数值类型
  • 布尔类型或null:什么都不渲染

生命周期

很多事物从创建到销毁的整个过程这个过程称之为生命周期。

constructor
如果不初始化state或不进行方法绑定则不需要为React组件实现构造函数。
constructor中通常只做两件事情

  • 通过给this.state赋值对象来初始化内部的state
  • 为事件绑定实例this

componentDidMount
componentDidMount会在组件挂在后插入DOM树中立即调用
操作

  • 依赖于DOM的操作可以在这里进行
  • 在此处发送网络请求就最好的地方官方建议
  • 可以在此处添加一些订阅会在componentWillUnmount取消订阅

componentDidUpdate
componentDidUpdate()会在更新后会被立即调用首次渲染不会执行此方法。
当组件更新后可以在此处对DOM进行操作。
如果你对更新前后的props进行了比较也可以选择在此处进行网络请求例如当props未发生变化时则不会执行网络请求

componentWillUnmount
componentWillUnmount() 会在组件卸载及销毁之前直接调用。
在此方法中执行必要的清理操作
例如清除timer取消网络请求或清楚
在componentDidMount()中创建的订阅等

import React, { Component } from 'react'

class Cpn extends Component {
  render () {
    return <h2>我是cpn组件</h2>
  }
  componentWillUnmount () {
    console.log('我调用了componentWillUnmount')
  }
}

export default class App extends Component {

  constructor() {
    super();

    this.state = {
      count: 1,
      isShow: true
    }
    console.log('执行了组件的constructor')
  }

  render () {
    console.log('执行了组件的render函数')

    return (
      <div>
        我是App组件
        <h2>当前计数{this.state.count}</h2>
        <button onClick={e => { this.increment() }}>+1</button>
        <hr />
        <button onClick={e => { this.changeShow() }}>切换</button>
        {this.state.isShow && <Cpn />}
      </div>
    )
  }

  increment () {
    this.setState({
      counter: this.state.counter + 1
    })
  }
  changeShow () {
    this.setState({
      isShow: !this.state.isShow
    })
  }

  componentDidMount () {
    console.log('执行了componentDidMount方法')
  }

  componentDidUpdate (previProps,preState,snapshot) {
    console.log('执行了componentDidUpdate方法')
  }
}

组件通信

父->子 props
子->父 itemOnclock

1.父传子-类组件

import React, { Component } from 'react'

class ChilCpn extends Component{
  // constructor(props){
  //   super(props);
  // }
  render(){
    const {name,age,height} = this.props
    return(
      <h2>子组件展示数据{name+' '+age+' '+height}</h2>
    )
  }
}

export default class App extends Component {
  render() {
    return (
      <div>
        <ChilCpn name='guo' age='18' height='1.55'/>
      </div>
    )
  }
}

2.父传子-函数组件-- 参数验证
效果
在这里插入图片描述

import React, { Component } from 'react'

import PropTypes from 'prop-types'

function ChildCpn(props){
  const {name,age,height} = props
  const {names} = props
  return (
    <div>
      <h2>{name+' '+ age+' '+height}</h2>

      {/*参数验证 */}
      <ul>
        {
           names.map((item,index)=>{
            return <li>{item}</li>
          })
        }
      </ul>
    </div>
  )
}
ChildCpn.propTypes = {
  name:PropTypes.string.isRequired, // 必传
  age:PropTypes.number,
  height:PropTypes.number,
  names:PropTypes.array
}

// 默认值
ChildCpn.defaultProps = {
  name:'wen',
  age:20,
  height:1.75,
  names:['111']
}

export default class App extends Component {
  render() {
    return (
      <div>
        <ChildCpn name='guo' age={18} height={1.55} names={['abc','mab']}/>
        <ChildCpn/>
      </div>
    )
  }
}

类组件的参数校验

class ChildCpn extends Component{
  // es6中class fields写法
  static propTypes = {

  }

  static defaultProps = {

  }
}

3.子组件传递父组件

import React, { Component } from 'react'

class CounterButton extends Component{
  render(){
    const {onClick} = this.props;
    return <button onClick= {onClick}>+1</button>
  }
}

export default class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      counter:0
    }
  }
  render() {
    return (
      <div>
        <h2>当前计数{this.state.counter}</h2>
        <button onClick= {e=>this.increment()}>+</button>
        <CounterButton onClick={this.increment.bind(this)} />
        <CounterButton onClick={e=>this.increment()} />
      </div>
    )
  }
  increment(){
    this.setState({
      counter:this.state.counter + 1
    })
  }
}

4.组件通信案例
APP.js

import React, { Component } from 'react'

import TabControl from "./TabControl"

export default class App extends Component {
  constructor(props){
    super(props);
    this.titles = ['精选','流行','新款']

    this.state = {
      currentTitle:'精选'
    }

  }
  render() {
    const {currentTitle} = this.state
    return (
      <div>
        <TabControl itemClick={index=>this.itemClick(index)} titles={this.titles}/>
        <h2>{currentTitle}</h2>
      </div>
    )
  }
  itemClick(index){
    console.log(index)
    this.setState({
      currentTitle:this.titles[index]
    })
  }
}

tabcontrol.js

import React, { Component } from 'react'
import PropTypes from 'prop-types'

export default class TabControl extends Component {
  constructor() {
    super()
    this.state = {
      currentIndex: 1
    }
  }
  render () {
    const { titles } = this.props;
    const { currentIndex } = this.state

    return (
      <div className="tab-control">
        {
          titles.map((item, index) => {
            return (
              <div key={index}
              className={'tab-item ' + (index === currentIndex ? 'active' : '')}
              onClick={e => this.itemClick(index)}>
              <span>{item}</span>
            </div>
            )
          })
        }
      </div>
    )
  }

  itemClick (index) {
    this.setState({
      currentIndex: index
    })
    const {itemClick} = this.props
    itemClick(index)
  }
}
TabControl.propTypes = {
  titles: PropTypes.array.isRequired
}
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6