1.setState不可变的数据
首先明确一点为了保证PureComponent以及我们为了实现项目优化自己写的shouldComponent能够正确渲染页面,setState不允许直接修改state中的数据,我们最好是将其备份一份,然后进行修改。
shouldComponentUpdate()传过来了两个参数
nextProps, nextState
nextProps : 最新的props
nextState : 最新的state
每一次在内部进行浅层比较,props以及state是否发生了变化,而如果我们直接修改state中的数据的话,这样最新的props和state永远是相同的,就不会重新调用render函数,实现页面数据实时刷新。
- 正确做法
import React, {
PureComponent } from 'react'
export default class App extends PureComponent {
constructor(props){
super(props);
this.state = {
movieList:[
{
name:'三国演义',price:20},
{
name:'水浒战纪',price:40},
{
name:'西游战记',price:90},
{
name:'红楼梦即',price:990},
]
}
}
render() {
return (
<div>
<ul>
{
this.state.movieList.map((item,index) => {
return (
<li key={
item.name}>{
index} 电影名称:{
item.name} ----- 电影票价格:{
item.price}
<p><button onClick={
e => this.priceAdd(index)}>price + 1</button></p>
</li>
)
})
}
</ul>
<button onClick={
e => this.addMovie()}>添加剧目</button>
</div>
)
}
addMovie(){
const newData = [...this.state.movieList];
newData.push({
name:'海的女儿',price:90})
this.setState({
movieList:newData
})
}
priceAdd(index){
const newData = [...this.state.movieList];
newData[index].price += 10;
this.setState({
movieList:newData
})
}
}
2.react全局事件传递(事件总线 event bus)
安装依赖库:event (yarn add event)
- events 基本使用
import React, {
PureComponent } from 'react'
// 引入事件发射器
import {
EventEmitter} from 'events'
const eventBus = new EventEmitter();
class Son extends PureComponent {
//监听事件
componentDidMount(){
eventBus.addListener('sayhello',this.handleSayHelloListener)
}
//取消事件监听
componentWillUnmount(){
eventBus.removeListener('sayhello',this.handleSayHelloListener)
}
//为了方便取消事件我们就把事件函数提取出来
handleSayHelloListener(args){
console.log(args)
}
render(){
return (
<div>
我是Son
</div>
)
}
}
class Father extends PureComponent {
constructor(props){
super(props)
this.state = {
}
}
render(){
return (
<div>
我是Father
<button onClick={
e => {
this.emitEvent()}}>我要给son发射事件</button>
</div>
)
}
emitEvent(){
/**
* 参数:第一个:事件的名称
* 第二个:可以传入多个东西
*/
eventBus.emit('sayhello','data数据')
}
}
export default class App extends PureComponent {
render() {
return (
<div>
<Son/>
<Father/>
</div>
)
}
}
3.受控组件(表单组件使用)
- 阻止表单默认提交行为
监听form表单的submit事件,然后阻止默认事件
<div>
<form onSubmit={
e => this.handleSubmit(e)}>
<label htmlFor="username">
userName:<input type="text" id='username' name='username'/>
</label>
<input type="submit" value='提交'/>
</form>
</div>
handleSubmit(event) {
event.preventDefault()
}
- 一个表单提交的简单演示
import React, {
PureComponent } from 'react'
export default class App extends PureComponent {
constructor(props){
super(props);
this.state = {
username:''
}
}
render() {
return (
<div>
<form onSubmit={
e => this.handleSubmit(e)}>
<label htmlFor="username">
userName:<input type="text"
id='username'
name='username'
value={
this.state.username}
onChange={
e => this.valueChange(e)}/>
</label>
<input type="submit" value='提交'/>
</form>
</div>
)
}
handleSubmit(event) {
event.preventDefault();
console.log('最终数据')
console.log(this.state.username)
}
valueChange(e){
this.setState({
username:e.target.value
})
}
}
- 多选项表单提交(优化代码)
import React, {
PureComponent } from 'react'
export default class App extends PureComponent {
constructor(props){
super(props);
this.state = {
username:'',
password:'',
email:''
}
}
render() {
return (
<div>
<form onSubmit={
e => this.handleSubmit(e)}>
<label htmlFor="username">
userName:<input type="text"
id='username'
name='username'
value={
this.state.username}
onChange={
e => this.handleValueChange(e)}/>
</label>
<p>
<label htmlFor="password">
password:<input type="text"
id='password'
name='password'
value={
this.state.password}
onChange={
e => this.handleValueChange(e)}/>
</label>
</p>
<p>
<label htmlFor="email">
email:<input type="text"
id='email'
name='email'
value={
this.state.email}
onChange={
e => this.handleValueChange(e)}/>
</label>
</p>
<input type="submit" value='提交'/>
</form>
</div>
)
}
handleSubmit(event) {
event.preventDefault();
const {
username, password, email} = this.state;
console.log(username,password,email)
}
//函数简单化处理
handleValueChange(e){
this.setState({
[e.target.name]:e.target.value
})
}
}
1.react高阶组件
- 高阶组件定义
高阶组件是参数为组件,返回值为新的组件的函数。
import React, {
PureComponent } from 'react'
class App extends PureComponent {
render() {
return (
<div>
APP:{
this.props.name}
</div>
)
}
}
function enhanceComponent(WrappedComponent){
class NewComponent extends PureComponent {
render() {
return <WrappedComponent {
...this.props}/>
}
}
return NewComponent;
}
const EnhanceComponent = enhanceComponent(App);
export default EnhanceComponent;
2.高阶组件的应用
- 增强props
如果一个组件之后需要增加某个属性,但是这个组件我们使用了很多次,所以我们要避免去一个个修改组件,可以定义一个高阶组件去完成。
import React, {
PureComponent } from 'react'
//定义一个高阶组件(增加每个用户的区域信息)
function enhanceRegionProps(WrappedComponent){
return props => {
return <WrappedComponent {
...props} region="中国"/>
}
}
class Home extends PureComponent {
render() {
return <h2>Home:{
`昵称:${
this.props.nickName} 等级:${
this.props.level} 区域:${
this.props.region}`} </h2>
}
}
const EnhanceHome = enhanceRegionProps(Home);
class About extends PureComponent {
render() {
return <h2>About:{
`昵称:${
this.props.nickName} 等级:${
this.props.level} 区域:${
this.props.region}`}</h2>
}
}
const EnhanceAbout = enhanceRegionProps(About);
class App extends PureComponent {
render() {
return (
<div>
app
<EnhanceHome nickName='codewhy' level='99'/>
<EnhanceAbout nickName='kobe' level='70'/>
</div>
)
}
}
export default App;
还有较多应用不叫高深,我下去再研究研究。。。。。