React-高级内容

1、使用 PropTypes 类型检查

官网:使用 PropTypes 类型检查

  • PropTypes 提供一系列验证器,可用于确保组件接收到的数据类型是有效的。当传入的 prop 值类型不正确时,JavaScript 控制台将会显示警告。出于性能方面的考虑,propTypes 仅在开发模式下进行检查。

  • 通过配置特定的 defaultProps 属性来定义 props 的默认值。

  • npm install --save prop-types

import React,{Component} from 'react';

import PropTypes from 'prop-types';

class TodoItem extends Component {
	constructor(props) {
	    super(props);
		this.handClick = this.handClick.bind(this);
	}
	
	render(){
		const {content,test} = this.props;
		return (<li onClick={this.handClick}>{test}-{content }</li>)
	}
	
	handClick(){
		const {itemDelete,index} = this.props;
		itemDelete(index);
	}
}

	TodoItem.propTypes = {
		test: PropTypes.string.isRequired,
		content: PropTypes.string,
		itemDelete: PropTypes.func,
		index: PropTypes.number,
	}
	
	TodoItem.defaultProps = {
	  test: 'stranger'
	}
	
export default TodoItem;
2、props,state,render之间的关系
  • 当组件的 state 与 props 发生变化的时候, render函数就会重新执行
  • 当父组件的 render 函数被运行时, 它的子组件的 render 函数也会被重新运行
    父组件demo:
import React,{Component,Fragment} from 'react';
import Test from './Test';

class TodoList extends Component{
	
	constructor(props) {
	    super(props);
		this.state = {
			inputValue: '',
		}

	}
	
	render(){
		// 当组件的 state 与 props 发生变化的时候, render函数就会重新执行.
		const {inputValue} = this.state;
		console.log("render");
		return (
			<Fragment>
				<Test content={inputValue}/>
			</Fragment>
		);
	}

export default TodoList;

子组件demo:

import React,{Component} from 'react';

class Test extends Component {
	render(){
		// 当父组件的 render 函数被运行时, 它的子组件的 render 函数也会被重新运行.
		console.log("Test Render");
		return <div>{this.props.content}</div>
	}
}

export default Test;
3、虚拟DOM的Diff算法

React 中虚拟dom(js对象) 的 diff 算法:

  1. diff算法: 找原始虚拟dom 和新的虚拟dom直接的差异。
  2. 数据发生改变的时候才会产生diff 算法。(state 或者 props 发生改变的时候,也就是 调用 SetState()的时候。)
  3. 虚拟dom同级比对,发现某一层dom 不对的话,其他的就不比对了,就会把这层以下的所有的dom全部替换为新的虚拟dom。
  4. 虚拟dom在循环的时候能不用index做key值就尽量不用。
4、ref的使用
  • ref可以帮助我们获取DOM元素:<input ref={(input) => { this.input = input }} />调用的时候就直接写this.input
  • setState是异步函数,会晚一点执行,或者整合执行,总之不会立即执行,setState( () =({}), () ={} )
    第一个参数是设置新的state,第二个参数是setState完成后的回调函数,如果想获取state更新后的dom节点,就必须写在回调函数里,有个先后顺序。
    this.ol.querySelectorAll(‘div’).length获取ol里div的长度(个数)
import React,{Component,Fragment} from 'react';
import TodoItem from './TodoItem';
import  './style.css';

class TodoList extends Component{
	
	constructor(props) {
	    super(props);
		this.state = {
			inputValue: '',
			list: [],
		}
		
		this.handleChange = this.handleChange.bind(this);
		this.handBtnClick = this.handBtnClick.bind(this);
		this.handItemDelete = this.handItemDelete.bind(this);
	}
	
	render(){
		// 当组件的 state 与 props 发生变化的时候, render函数就会重新执行.
		const {inputValue} = this.state;
		return (
			<Fragment>
				<div>
					<label htmlFor="inputAra">输入内容</label>
					<input className="input" id ="inputAra"
						value={this.state.inputValue} 
						onChange={this.handleChange} 
						ref={(input)=>{this.input = input}}
					/> 
					<button onClick={this.handBtnClick}>提交</button>
				</div>
				<ul ref={(ul)=>{this.ul= ul}}>
					<div>
						{this.getTodoItem()}
					</div>
				</ul>
			</Fragment>
		);
	}
	
	handleChange(e) {
		// 函数,异步,性能提升
		const value = this.input.value;
		// const value = e.target.value;
		this.setState(() => ({
			inputValue:value,
		}));
		
	}
	
	handBtnClick() {
		this.setState((prevState) => ({
			list: [...prevState.list,prevState.inputValue],
			inputValue: '',
		}),()=>{
			 console.log(this.ul.querySelectorAll('li').length);
		});
		// console.log(this.ul.querySelectorAll('li').length);
	}

export default TodoList;
5、生命周期

**组件生命周期函数是指在某一时刻自动会被执行的函数
官网-生命周期
在这里插入图片描述

	// 组件被挂载之前执行
	componentWillMount(){
			console.log("componentWillMount");
		}
	
	render(){
	        // 当组件的 state 与 props 发生变化的时候, render函数就会重新执行.
			console.log("render");
			return ();
	}

   // 组件被更新之前,自动执行
	shouldComponentUpdate(){
		console.log("shouldComponentUpdate");
		return true;
	}
	
	// 组件被更新之前,自动执行,但是前提是shouldComponentUpdate返回true时才会执行
	componentWillUpdate(){
		console.log("componentWillUpdate");
		return true;
	}
	// 组件更新完之后,自动执行	
	componentDidUpdate(){
		console.log("componentDidUpdate");
	}
	
	// 组件被挂载在页面之后,自动执行		
	componentDidMount(){
		console.log("componentDidMount");
	}
	
	// 一个组件要从父组件接收参数
	// 只要父组件的render函数被重新执行了,子组件这个生命周期函数就会执行
	componentWillReceiveProps(){
		console.log("child componentWillReceiveProps");
	}
	
	// 组件被卸载时执行
	componentWillUnmount(){
		console.log("child componentWillUnmount");
}
	
  • 所有的生命周期函数都可以不存在,但是render函数必须存在;因为react中的组件继承了Component组建的属性,这个组件中内置了其它生命周期函数,没有内置render函数的默认实现。
  • 性能优化:父组件数据发生变化时,子组件也会刷新,但是很多时候的刷新是不必要的,可以在子组件生命周期函数中加以判断,只有特定条件下子组件才更新。
	// 子组件性能优化使用
	shouldComponentUpdate(nextProps,nextState){
		if (nextProps.content!== this.props.content){
			return true;
		} else {
			return false;
		}
	}
  • 利用生命周期函数做axios请求,yarn add axios, 然后import axios from 'axios’即可使用。
	componentDidMount(){
		axios.get('/api/todolist')
		.then(()=>{alert("success")})
		.catch(()=>{alert("error")})
	}
6、Charles来模拟后端数据
  • 数据的mock就是数据的模拟
// npm install axios
import axios from 'axios'
componentDidMount() {
     axios.get('./api/todolist')
         .then((res) =({
             this.setState(() =( ({
                list: [...res.data]
              }))
          })
         .catch(() =({console.log("erro")})
   }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值