setState
setState用法参考 最终都是返回一个新的state对象让其合并
核心
setState并非真异步,只是看上去像异步。在源码中通过isBatchingUpdates来判断setState是先存进state队列还是直接更新,如果值为true则执行异步操作,为false则直接更新 场景 在react可以控制的地方,就为true,比如React生命周期事件和合成事件中,都会先存入队列,延迟更新。 在react无法控制的地方,比如原生事件,addEventListener、setTimeout、setInterval等,只能同步更新 合成事件 在react中自定义的方法 合成事件官方文档
// handleOk和handleCancel就为合成事件
<Modal visible={this.state.isModalVisible} onOk={this.handleOk} onCancel={this.handleCancel}>
<p>是否删除该项</p>
</Modal>
React中事件绑定及优化
- React中的事件绑定存this指向的问题,在render函数中的JSX语法中绑定事件函数,this为undefined,需要讲this指向组件类本身。通过箭头函数或者call、apply、bind改变this指向。
// 箭头函数
<Button type="text" danger onClick={() => this.delHandel(index)}>删除</Button>
// bind改变this指向,通过bind绑定会返回一个改变this指向后的新函数
<Button type="text" danger onClick={this.delHandel.bind(this, index)}>删除</Button>
-
在 render 方法中使用 Function.prototype.bind 会在每次组件渲染时创建一个新的函数,可能会影响性能
-
解决通过bind绑定会影响性能的问题(使用bind且要传参)
解决方法一:通过先在constructor中完成this的bind,然后在render函数中直接使用。而参数通过dataset来获取
const A = 65 // ASCII character code
class Alphabet extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
justClicked: null,
letters: Array.from({length: 26}, (_, i) => String.fromCharCode(A + i))
};
}
handleClick(e) {
this.setState({
justClicked: e.target.dataset.letter
});
}
render() {
return (
<div>
Just clicked: {this.state.justClicked}
<ul>
{this.state.letters.map(letter =>
<li key={letter} data-letter={letter} onClick={this.handleClick}>
{letter}
</li>
)}
</ul>
</div>
)
}
}
React中条件渲染和列表渲染
React中父子组件传值
- 父组件通过属性的方式向子组件传值
// 父组件向CardList组件传递list属性值
<CardList list={this.state.list}/>
// 子组件通过this.props接收
class CardList extends React.Component {
render() {
return (
<Card className="mt-10">
{
this.props.list.length > 0?(
this.props.list.map((item, index)=> {
return (
<div className="flex jc-sb ai-c" key={index}>
<div>{item}</div>
<Button type="text" danger>删除</Button>
</div>
)
})
):(
<p>暂无数据</p>
)
}
</Card>
)
}
}
export default CardList
- 子组件向父组件传值,通过执行父组件传递的回调函数
// 父组件
<CardList list={this.state.list} delHandel={(index) => this.delHandel(index)}/>
// 子组件
import React from 'react'
import { Button, Card } from 'antd'
class CardList extends React.Component {
render() {
return (
<Card className="mt-10">
{
this.props.list.length > 0?(
this.props.list.map((item, index)=> {
return (
<div className="flex jc-sb ai-c" key={index}>
<div>{item}</div>
<Button type="text" danger onClick={() => this.delHandel(index)}>删除</Button>
</div>
)
})
):(
<p>暂无数据</p>
)
}
</Card>
)
}
delHandel(index) {
console.log(index)
this.props.delHandel(index)
}
}
export default CardList
React组件传值PropTypes类型检查
- 安装prop-types
npm i prop-types -Syarn add prop-types - 使用
import PropTypes from 'prop-types'
class CardList extends React.Component {}
CardList.propTypes = {
// props类型,isRequired为必传
list: PropTypes.array.isRequired
}
CardList.defaultProps = {
// 默认值
list: []
}
export default CardList
React中使用refs获取DOM
- 可以操作 dom
- react 是不建议使用 ref 的,因为 setState 是一个异步函数不会被立即执行,dom 的数据更新并不及时,如果你希望页面更新之后再去更新 dom,你要把获取 dom 的语法方法在 setState 第二个参数的函数里面(回调函数)
this.setState(
(prevState) => {},
() => {
console.log("获取更新之后的dom")
}
);
React动画
- 使用 react-transition-group
- 安装
npm install react-transition-group或yarn add react-transition-group - 参考文档
React样式模块 styled-components
- 安装
npm install --save styled-components或yarn add styled-components - 参考文档
跨域,使用http-proxy-middleware 中间件
- 安装
npm install http-proxy-middleware --save或yarn add http-proxy-middleware - 在 src 下创建 setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
createProxyMiddleware('/api', {
target: 'http://localhost:8000',
})
);
};
React.Component 和 React.PureComponent的区别
-
PureComponent优点:不需要开发者自己实现 shouldComponentUpdate,就可以自动判断来提升性能
-
PureComponent缺点:可能会因深层的数据不一致而产生错误的否定判断,从而shouldComponentUpdate结果返回false,界面得不到更新。
-
如果你使用 immutable 进行数据管理,可以将组件的继承 Component 都改成 PureComponent 可以很好的提升性能.如果没有使用 immutable,建议还是使用 component,因为这个有时候会遇到小坑,如果没有使用 immutable 进行数据管理,你也可以自己写 shouldComponentUpdate 进行性能的优化
-
PureComponent 内置了类似组件 shouldComponentUpdate 钩子,对于与自己组件无关的数据改变,不会重新渲染,大大提高了性能.
JSX中return后面加括号表示什么意思
- JS中圆括号表示执行符号,在render中是给babel-jsx解析用的
- return中的圆括号是为了代码换行,不用括号的话只能写一行