最新更新时间: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元素相互转换
//'<span></span>'
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
}
参考资料
- 无
感谢阅读,欢迎评论^-^