基本函数
// 组件即将被挂载到页面里执行
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