您现在的位置是:主页 > news > 进销存/江门关键词排名优化

进销存/江门关键词排名优化

admin2025/4/30 3:44:13news

简介进销存,江门关键词排名优化,女包建设网站前的市场分析,网站内容发布平台源码文章目录1. 基本使用2. 使用setState操作state数据3. 案例:toDoList4. 案例:购物车1. 基本使用 要点: 成员属性 state 它是一个特殊的属性,它是当前类的私有数据,只有在当前的组件中才能操作里面的数据状态( state )…

进销存,江门关键词排名优化,女包建设网站前的市场分析,网站内容发布平台源码文章目录1. 基本使用2. 使用setState操作state数据3. 案例:toDoList4. 案例:购物车1. 基本使用 要点: 成员属性 state 它是一个特殊的属性,它是当前类的私有数据,只有在当前的组件中才能操作里面的数据状态( state )…

文章目录

  • 1. 基本使用
  • 2. 使用setState操作state数据
  • 3. 案例:toDoList
  • 4. 案例:购物车


1. 基本使用

要点:

  1. 成员属性 state 它是一个特殊的属性,它是当前类的私有数据,只有在当前的组件中才能操作里面的数据
  2. 状态( state )即数据,是组件内部的私有数据,只能在组件内部使用,和vue中data差不多,不过它没有像vue中的data进行了数据劫持
  3. state的值是对象,表示一个组件中可以有多个数据
  4. 通过this.state来获取状态,react 中没有做数据代理
  5. 想要修改 state 数据值同时让视图更新则需要调用专用的方法 this.setState
  6. state 它是类的一个成员属性
  7. state 中的数据可读可写的

使用:

import React, { Component } from 'react';class App extends Component {// 初始化方式1// state = {//   num: 100// }// 初始化方式2constructor(props) {super(props);this.state = {num: 100}}addNum(evt, n = 1) {// 同步修改数据,它不会触发视图更新this.state.num += nthis.forceUpdate()console.log(this.state.num);}render() {return (<div>{/* 在视图中读取state中的数据 */}<h3>{this.state.num}</h3><button onClick={evt => this.addNum(evt, 2)}>累加</button></div>);}
}export default App;

在这里插入图片描述

2. 使用setState操作state数据

概述:

修改 state 中的 num 属性数据的同时,让视图更新,用到专门用来修改 state 中数据的方法 setState。

语法:

# 语法1
this.setState({key:value
})# 语法2  推荐
this.setState(state => {return {key:value}
})

使用:

import React, { Component } from 'react';class App extends Component {state = {num: 100}addNum(evt, n = 1) {// 对象方式更新 批处理  => 数组【队列】   虚拟dom比对// 它是一个异步操作this.setState({num: this.state.num + 1})console.log(this.state.num);// this.setState({//   num: this.state.num + 1// }, () => {//   // 回调函数中就可以得到最新的状态数据//   console.log(this.state.num);// })}render() {return (<div>{/* 在视图中读取state中的数据 */}<h3>{this.state.num}</h3><button onClick={evt => this.addNum(evt, 2)}>累加</button></div>);}
}export default App;

在这里插入图片描述

注意:

注意执行结果中,虽然视图发生了更新,但是控制台打印 state 中的数据并没有发生改变,说明这里的更新数据是异步操作。

之所以是异步操作,是因为 React 在这里做了批处理。即当执行多次修改数据的操作时,React 并不会立即执行,而是将这些操作存入一个异步队列中,然后再进行统一处理,这样做可以提升性能。假如我现在要修改 3 次数据,不用批处理需要更新视图 3 次,而如果进行批处理的话,只需要更新视图一次。更新视图需要进行 dom 比对,只比 1 次显然比比对 3 次性能更好。

关于 setState 方法(React 批处理)中的对象合并:

import React, { Component } from 'react';class App extends Component {state = {num: 100}addNum(evt, n = 1) {this.setState({num: this.state.num + 1})this.setState({num: this.state.num + 2})this.setState({num: this.state.num + 3})console.log(this.state.num);// 函数,它不会合并,它会依次执行  == 建议多用函数方式,保证数据完整性// this.setState(state => ({//   num: state.num + 1// }))// this.setState(state => ({//   num: state.num + 2// }))// this.setState(state => ({//   num: state.num + 3// }))// console.log(this.state.num);//6}render() {return (<div>{/* 在视图中读取state中的数据 */}<h3>{this.state.num}</h3><button onClick={evt => this.addNum(evt, 2)}>累加</button></div>);}
}export default App;

在这里插入图片描述

从图中运行结果可以看出,当我们多次修改数据时,视图只针对最后一次修改作出渲染。这是因为在 React 批处理中(批处理队列是一个集合,这里看作是一个对象),会进行对象合并。什么意思呢?首先对象的 key 值是唯一的,当 key 值 num 已经存在时,再传 num 会对对象中已经存在的 num 进行修改,即对象中有效的 num 的值是最后一次操作:this.state.num + 3

补充说明:批处理队列的底层进行的是[...obj1,...obj2]的操作,所以重复的项只会出现一次。而函数方式的批处理进行的是[fn1,fn2...],所以会依次执行。这里的解释过于牵强和抽象,只是为了简单理解和记忆,更加完整的阐述需要了解底层之后,再加深理解。

关于 setState 方法的同步操作:

react17 及之前版本,如果你把当前的操作不写在合成事件中,则 setState 它就是同步的,react18全是异步的。

setState 在执行的过程中,它会判断当的执行环境,如果为宏任务等,则它会立即执行。

也就是说, setState 方法只要写在合成事件处理方法中,它就是异步的;只要不写在合成事件中,它都是同步。(仅限于 react17 及之前版本)

比如 setState 方法写在宏任务中或者写在原生事件中就是同步的。

例如下面这样的写法就是同步操作:

import React, { Component } from 'react';class App extends Component {// setState它是同步的也是异步的// 只要写在合成事件处理方法中,它就是异步// 只要不写在合成事件中,它都是同步state = {num: 100}addNum(evt, n = 1) {setTimeout(() => {// 写在宏任务中的setState它是同步的this.setState({num: this.state.num + 3})console.log(this.state.num);}, 0);}// 类似于vue中的mounted方法// componentDidMount() {//   // 写在原生事件中它的setState也是同步的//   // document.onclick = () => {//   //   this.setState({//   //     num: this.state.num + 3//   //   })//   //   console.log(this.state.num);//   // }// }render() {return (<div>{/* 在视图中读取state中的数据 */}<h3>{this.state.num}</h3><button onClick={evt => this.addNum(evt, 2)}>累加</button></div>);}
}export default App;

在这里插入图片描述

3. 案例:toDoList

import React, { Component } from 'react';class App extends Component {state = {todos: []}onEnter = evt => {if (evt.keyCode === 13) {let title = evt.target.value.trim()// 方案1// let todos = this.state.todos.concat({ id: Date.now(), title, done: false })// this.setState({ todos })// 方案2// this.state.todos.push({ id: Date.now(), title, done: false })// this.forceUpdate() // 这里也可以写成这一句:this.setState({})// 如果你setState写了一个空对象,则它会更新视图一次// this.setState({})// 如果你写了为null,setState不会做任何事件,相当于没有调用// this.setState(null)// 方案3:更新数据,推荐,确保数据的完整性this.setState(state => ({todos: [...state.todos, { id: Date.now(), title, done: false }]}), () => evt.target.value = '')}}del = tid => () => {this.setState(state => ({todos: state.todos.filter(({ id }) => id != tid)}))}delIndex = index => () => {this.state.todos.splice(index, 1)this.setState({})}render() {return (<div><div><input type="text" onKeyUp={this.onEnter} /></div><hr /><ul>{this.state.todos.map((item, index) => (<li key={item.id}><span>{item.title}</span>{/* 按 id 删除 */}<span onClick={this.del(item.id)}>删除</span>{/* 按索引删除 */}<span onClick={this.delIndex(index)}>删除</span></li>))}</ul></div>);}
}export default App;

在这里插入图片描述

注意:

setState 还有两种扩展用法:

  1. 如果你setState写了一个空对象,则它会更新视图一次

    this.setState({})

  2. 如果你写了为null,setState不会做任何事件,相当于没有调用

    this.setState(null)

4. 案例:购物车

import React, { Component } from 'react';class App extends Component {state = {carts: [{ id: 1, name: '水果手机14', price: 1, num: 1 },{ id: 2, name: '大米手机14', price: 1, num: 2 },{ id: 3, name: '一般手机14', price: 1, num: 3 },]}setNum = (n, index) => {// 方案1this.state.carts[index]['num'] += nif (this.state.carts[index]['num'] <= 1) this.state.carts[index]['num'] = 1if (this.state.carts[index]['num'] >= 5) this.state.carts[index]['num'] = 5this.setState({})// 方案2// this.setState(state => {//   state.carts[index]['num'] += n//   let carts = state.carts//   return { carts }// 同等于 return {carts:carts}// })}totalPrice = () => {return this.state.carts.reduce((p, c) => {p += c.num * c.pricereturn p}, 0)}render() {return (<div><table width='600' border='1'><thead><tr><th>ID</th><th>名称</th><th>价格</th><th>数量</th></tr></thead><tbody>{this.state.carts.map((item, index) => (<tr key={item.id}><td>{item.id}</td><td>{item.name}</td><td>{item.price}</td><td><button onClick={() => this.setNum(-1, index)}>---</button><span>{item.num}</span><button onClick={() => this.setNum(1, index)}>+++</button></td></tr>))}</tbody></table><hr /><h3>{this.totalPrice()}</h3></div>);}
}export default App;

在这里插入图片描述