React学习总结

最新更新时间:2019年09月07日17:17:12

《猛戳-查看我的博客地图-总有你意想不到的惊喜》

本文内容:主要记录作者在使用react的过程中,学习到的新的知识点和难点。

父组件触发子组件方法

在父组件中通过refs获取子组件对象,然后直接调用即可

//这是一个父组件 parent.js
import Apple from './Apple'
export default class Fruit extends React.Component{

	constructor(props) {
		super(props);
		this.state = {};
	}
	
	componentDidMount(){
		//父组件执行子组件方法
		this.refs.apple.changeStatus();
	}
	
	render(){
		return (
			<div>
				<Apple ref="apple" />
			</div>
		)
	}
}
//这是一个子组件 child.js
class Apple extends React.Component{

	changeStatus(){
		console.log('父组件触发了这个方法')
	}
	
	render(){
		return (
			<div></div>
		)
	}
}

父组件数据变化拦截子组件dom更新

//父组件传递给子组件的数据,在子组件的constructor中用state接收,以扩展运算符的形式赋值给子组件,相当于数据深拷贝,切断了引用数据类型数据指针的指向,从而实现了当父组件的redux数据变化触发父组件更新时,但不能触发子组件数据更新。
export default class Fruit extends React.Component{

	constructor(props) {
		super(props);
		this.state = {
			data: {...this.props.data}
		};
	}
	
	render(){
		return (
			<div>{this.state.data}</div>
		)
	}
}

this.props.children

父子组件通信过程中,父组件可以给子组件传递属性、方法和组件。

//这是一个父组件 parent.js
import Apple from './Apple'
export default class Fruit extends React.Component{

	constructor(props) {
		super(props);
		this.state = {
			name : 'wanshaobo'
		};
	}
	
	getAge(age){
		console.log('i am ' + age + ' years old!')
	}
	
	render(){
		return (
			<div>
				<p>这是标题</p>
				<Apple
					name={this.state.name}
					age={(age)=>{this.getAge(age)}}
				>
					<span>1</span>
					<span>2</span>
					<span>3</span>
				</Apple>
			</div>
		)
	}
}
//这是一个子组件 child.js
class Apple extends React.Component{
	render(){
		const { name,age,children } = this.props
		return (
			<div>
				{/*获取父组件传递过来的组件的第一种方法*/}
				{children}
				{/*获取父组件传递过来的组件的第二种方法*/}
				{
					React.Children.map(children,(child,index) => {
						return child;
					})
				}
				{/*获取父组件传递过来的组件的数量*/}
				{React.Children.count(children)}
				<span>4</span>
				<span>5</span>
				<span>6</span>
				{/*获取父组件传递过来的属性*/}
				<span>{name}</span>
				{/*执行父组件传递过来的方法*/}
				<div onClick={()=>{age(18)}}>点击设置年龄</div>
			</div>
		)
	}
}

this.props.children属性,表示组件的所有子节点,值有三种情况:

  • 如果当前组件没有子节点,它就是undefined
  • 如果有一个子节点,数据类型是Object
  • 如果有多个子节点,数据类型就是array

props 初始化

export default class Fruit extends React.Component{

	//组件内部的声明方法
	static defaultProps = { 
		name: 'wanshaobo' || this.props.fromParentData.name
	}
	constructor(props) {
		super(props);
		this.state = {};
	}
	
	render(){
		return (
			<div></div>
		)
	}
}
//组件外部的声明方法
Greeting.defaultProps = {    
	name: 'props的默认值!' || this.props.fromParentData.name
};

性能优化

以下总结出开发过程中的注意事项:

  • 绑定函数,在 constructor 中绑定
  • 父组件状态发生变化,不应该触发状态没有发生变化的子组件重新渲染;
  • 子组件使用React.PureComponent 或 改写 shouldComponentUpdate方法;
  • PureComponent 和 shouldComponentUpdate 不能同时使用;
  • PureComponent仅对数据做浅比较,因此对非引用数据类型有效,对引用数据类型无效。如果是引用数据类型,需要在shouldComponentUpdate中做深比较;
  • 使用Immutable.js,三个特征:
  • Immutable对象创建后不可变,如果改变会返回新的Immutable对象;
  • Persistent Data Structure - 持久化数据结构,使用旧数据创建新数据时,旧数据内容可以且不变
  • Structural Sharing - 结构共享,子节点发生变化,只影响父节点的变化,其他节点(兄弟节点)不受影响;
  • 父组件向子组件传参,props 拆分为基本数据类型
  • 父组件向子组件传递函数,在 constructor 中绑定
  • render中用到的常量提取成模块变量静态成员
import React from 'react'

import * as styles from './index.scss'

import { secondToDate } from '@/utils/func'

//模块变量
const temp = {a:1, b:2}

export default class Timer extends React.Component{

  constructor(props){
    super(props);
    this.state = {
    	age: ''
    }
    this.handleClick = this.handleClick.bind(this);
    //静态成员
    this.temp = [1,2,3]
  }
  
  componentWillMount() {
  
  }

  componentDidMount() {
  
  }  
  
  shouldComponentUpdate(nextProps={}, nextState={}, nextContext={}) {
  	const curProps = this.props || {}, curState = this.state || {};
  	//先比较数量
	if (Object.keys(curProps).length !== Object.keys(nextProps).length ||
	      Object.keys(curState).length !== Object.keys(nextState).length) {
	    return true;
	}
  	
  	//不需要比较全部数据,仅仅比较发生变化的数据,函数/不变数据不需要判断
  	//当前的数据和下一次传入的数据不一致,触发渲染
  	
  	//非引用类型数据
  	if(this.state.age != nextProps.data.age){
  		this.state.age == nextProps.data.age
  		return true
	}
	return false
  }

  componentWillUnmount() {
  
  }
  
  handleClick(){
	console.log('click')
  }

  render(){
    return <div onClick={this.handleClick}/*如果此处需要传参怎么办?*/
    	a={temp}
    	b={this.temp}
    >
    {this.props.data.age}
	</div>
  }
}

字符串和DOM元素相互转换

//''
function str2dom(str){
	let div = document.createElement("div");
	div.innerHTML = str
	div.childNodes[0].innerHTML = 'abc'
	return div.childNodes[0];
}

function dom2str(dom){
	let tmpNode = document.createElement('div')
	tmpNode.appendChild(dom)
	return tmpNode.innerHTML
}

参考资料

感谢阅读,欢迎评论^-^

打赏我吧^-^

你可能感兴趣的:(web前端开发)