6.React 基础记录

786 阅读3分钟

基本函数

// 组件即将被挂载到页面里执行
componentWillMount() {
  console.log('componentWillMount')
}

// 组件即将被挂载到页面里执行
componentDidMount() {
  console.log('componentDidMount')
}

// 组件被更新之前会执行
shouldComponentUpdate(nextProps, nextState, nextContext) {
  console.log('shouldComponentUpdate')
  return true
}

// 组件更新之前会自动执行,在shouldComponentUpdate之后执行,但取决于此方法的返回值,如返回true则执行,如是false则不执行
componentWillUpdate(nextProps, nextState, nextContext) {
  console.log('componentWillUpdate')
}

// 组件更新之后自动执行
componentDidUpdate(prevProps, prevState, snapshot) {
  console.log('componentDidUpdate')
}

// 当props参数接收时执行
// 如果这个组件第一次存在于父组件中,不会执行
// 如果这个组件之前已经存在于父组件中则会执行
componentWillReceiveProps(nextProps, nextContext) {
  console.log('componentWillReceiveProps')
}
// 组件卸载时,相当于Vue的beforeDestroy
componentWillUnmount() {
  console.log('componentWillUnmount')
}

应用场景

场景1

说明,父组件中render函数重新执行了,则子组件的render函数也会重新执行,这时候有性能损耗,但是有时候并不希望这种情况

  // 是否需要更新钩子函数
  // 子组件判断狭隘一个传入的content值是否和当前值相同,如不相同则return true来更新,否则就不更新
  shouldComponentUpdate(nextProps, nextState, nextContext) {
    return nextProps.content !== this.props.content;
  }

场景2

ajax请求需要在哪获取,类比于Vue的created钩子函数,我们需要在componentDidMount()函数中获取并网state中赋值

PropTypes

import PropTypes from 'prop-types'

TodoItem.propTypes = {
  content: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  deleteItem: PropTypes.func,
  index: PropTypes.number
}

实例

import React, { Component, Fragment } from 'react'
import './style.css'
import TodoItem from './TodoItem'

class TodoList extends Component {

  constructor(props) {
    super(props)
    // 组件状态,类似于Vue中data
    this.state = {
      inputValue: 'hello',
      list: ['学习Vue', '学习React']
    }

    this.handleInputChange = this.handleInputChange.bind(this)
    this.handleItemRemove = this.handleItemRemove.bind(this)
  }

  // 绑定值value={this.state.inputValue} 类似于Vue :value="inputValue"
  // 绑定事件{this.handleInputChange} 类似于Vue @on-change="handleInputChange"
  render() {
    console.log('render')
    return (
      <Fragment>
        <div>
          {
            /*这是一个注释*/
            // ref= { (input)=>{ this.input=input} } 其实就相当于Vue中的refs,这里默认给this.input赋予了当前的dom元素
          }
          <label htmlFor="insertArea">输入内容</label>
          <input className="input" id="insertArea"
                 value={this.state.inputValue}
                 onChange={this.handleInputChange}
                 ref={(input) => {
                   this.input = input
                 }}/>
          <button onClick={this.handleBtnClick}>提交</button>
        </div>
        <ul>{this.getTodoItem()} </ul>
      </Fragment>
    )
  }

  getTodoItem() {
    /*dangerouslySetInnerHTML={{__html: item}} 表示这里输入了标签内容,就会直接渲染一个标签*/
    return this.state.list.map((item, index) => {
      return (
        <TodoItem content={item} key={index} index={index}
                  deleteItem={this.handleItemRemove}/>
      )
    })
  }

  // 输入框响应
  handleInputChange(e) {
    // 保存响应式类似于vue this.$set(this.state,{})
    // this.setState({
    //   inputValue: e.target.value
    // })
    // 新语法
    const value = e.target.value
    // 获取更新后的dom要在setState函数后执行,类似Vue的nextTick
    console.log(this.input.value)
    this.setState(() => ({
      inputValue: value
    }))
  }

  // 按钮提交
  handleBtnClick = () => {
    if (this.state.inputValue.length === 0) return
    this.setState((prevState) => ({
      list: [...prevState.list, prevState.inputValue],
      inputValue: ''
    }))
  }

  // 移除一个
  handleItemRemove(index) {
    // immutable state 不允许我们做任何改变
    this.setState((prevState) => {
      let list = [...prevState.list]// 拷贝数组
      list.splice(index, 1)
      return {list}
    })
  }
}

export default TodoList

打包注意事项

react打包路径的注意事项,需要在package.json添加一个 "homepage": "."表示相对于当前目录下的根路径,否则应该配置为/xxx项目

根据path.js配置文件下的代码可以知道原因

const publicUrlOrPath = getPublicUrlOrPath(
  process.env.NODE_ENV === 'development',
  require(resolveApp('package.json')).homepage,
  process.env.PUBLIC_URL
);

打包环境下使用package.homepage 或者配置的PUBLIC_UIL

项目中使用图片引用时,不能直接写/images,根目录默认是从public目录下寻找,如发布后包含二级目录,则会丢失文件,所以引用的时候需要判断当前的环境

const basePath = process.env.NODE_ENV === 'development' ? '' : '.'

let imgUrl = basePath + '/images/ds.webp',

这种方式可以解决引用路径问题,否则,使用图片时将图片放置于assets目录下直接用相对路径即可

相关连接

最近在学习react开发,整理几篇笔记方便自己查询使用,下面是连接地址

1.React 之 react-transition-group

2.React之 redux、react-redux、redux-thunk

3.React 之 immutable 和 redux-immutable

4.React 之react-router-dom

5.React 之 react-loadable

6.React 基础记录

7.React 使用less等预处理器配置