React学习07-React扩展知识

news2024/11/16 11:25:36

setState

setState更新状态的2种写法:

  1. setState(stateChange, [callback])------对象式的setState
    1. stateChange为状态改变对象(该对象可以体现出状态的更改)
    2. callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用
  2. setState(updater, [callback])------函数式的setState
    1. updater为返回stateChange对象的函数
    2. updater可以接收到stateprops
    3. callback是可选的回调函数, 它在状态更新、界面也更新后(render调用后)才被调用
import React, { Component } from 'react'

export default class Demo extends Component {

  state = {count: 0}

  inicrement = () => {
    /* 对象式的setState */
    // 1.获取原来的count值
    // const {count} = this.state
    // // 2.更新状态
    // this.setState({count: count+1}, () => {
    //     console.log(this.state.count) // 1
    // })
    // // console.log(this.state.count) // 0

    /* 函数式的setState */
    // this.setState((state, props) => {
    //     return {count: state.count+1}
    // })
    this.setState(state => ({count: state.count+1})) // 简写
  }

  render() {
    return (
      <div>
        <h1>当前求和为:{this.state.count}</h1>
        <button onClick={this.inicrement}>点击+1</button>
      </div>
    )
  }
}
  1. 对象式的setState是函数式的setState的简写方式(语法糖)

  2. 使用原则:

    (1).如果新状态不依赖于原状态 => 使用对象方式

    (2).如果新状态依赖于原状态 => 使用函数方式

    (3).如果需要在setState()执行后获取最新的状态数据,要在第二个callback函数中读取

lazyLoad

路由组件的懒加载:

  1. 通过Reactlazy函数配合import()函数动态加载路由组件 => 路由组件代码会被分开打包
  2. 通过<Suspense fallback=?><Suspense/>指定在加载得到路由打包文件前显示一个自定义loading界面
import React, { Component, lazy, Suspense } from 'react'
import {NavLink, Route} from 'react-router-dom'
// import About from './About'
// import Home from './Home'

const About = lazy(() => import('./About'))
const Home = lazy(() => import('./Home'))


export default class Demo extends Component {

    render() {
        return (
            <div>
                <div className="row">
                    <div className="col-xs-offset-2 col-xs-8">
                        <div className="page-header"><h2>React Router Demo</h2></div>
                    </div>
                </div>
                <div className="row">
                    <div className="col-xs-2 col-xs-offset-2">
                        <div className="list-group">
                            <NavLink className="list-group-item" to="/about">About</NavLink>
                            <NavLink className="list-group-item" to="/home">Home</NavLink>
                        </div>
                    </div>
                    <div className="col-xs-6">
                        <div className="panel">
                            <div className="panel-body">
                                <Suspense fallback={<h1>Loading...</h1>}>
                                    <Route path="/about" component={About}/>
                                    <Route path="/home" component={Home}/>
                                </Suspense>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}

GIF 2022-5-22 22-47-29.gif

Hooks

Hook是React 16.8.0版本增加的新特性/新语法,可以在函数组件中使用 state 以及其他的 React 特性

State Hook

State Hook让函数组件也可以有state状态,并进行状态数据的读写操作

  1. 语法: const [xxx, setXxx] = React.useState(initValue)
  2. useState()说明:
    • 参数: 第一次初始化指定的值在内部作缓存
    • 返回值: 包含2个元素的数组, 第1个为内部当前状态值, 第2个为更新状态值的函数
  3. setXxx()2种写法:
    • setXxx(newValue): 参数为非函数值, 直接指定新的状态值, 内部用其覆盖原来的状态值
    • setXxx(value => newValue): 参数为函数, 接收原本的状态值, 返回新的状态值, 内部用其覆盖原来的状态值
import React from 'react'

export default function Demo() {
    const [count, setCount] = React.useState(0)
    const [name, setName] = React.useState('tom')

    function add() {
        // setCount(count + 1) // 第一种写法
        setCount(count => count + 1) // 第二种写法
    }

    // const add = () => {
    //     setCount(count + 1)
    // }

    // console.log(add)

    function change() {
        setName('jerry')
    }

    return (
        <div>
            <h2>当前求和为:{count}</h2>
            <h2>我的名字是:{name}</h2>
            <button onClick={add}>点击+1</button>
            <button onClick={change}>点击改名</button>
        </div>
    )
}

GIF 2022-5-23 20-16-52.gif

Effect Hook

Effect Hook 可以在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)

  1. React中的副作用操作:

    * 发ajax请求数据获取
    
    * 设置订阅 / 启动定时器
    
    * 手动更改真实DOM
    
  2. 语法和说明:

      useEffect(() => { 
        // 在此可以执行任何带副作用操作
        return () => { // 在组件卸载前执行
          // 在此做一些收尾工作, 比如清除定时器/取消订阅等
        }
      }, [stateValue]) // 如果指定的是[], 回调函数只会在第一次render()后执行,即什么都不监听
    
  3. 可以把 useEffect Hook 看做如下三个函数的组合
    * componentDidMount()
    * componentDidUpdate()
    * componentWillUnmount()

import React from 'react'
import ReactDOM from 'react-dom'
export default function Demo() {
    const [count, setCount] = React.useState(0)

    React.useEffect(() => {
        let timer = setInterval(() => {
            setCount(count => count + 1)
        }, 1000)
        return () => {
            clearInterval(timer)
        }
    }, [])

    function add() {
        // setCount(count + 1) // 第一种写法
        setCount(count => count + 1) // 第二种写法
    }

    function unmount() {
        // 这是18的写法:目前卸载组件能成功卸载但会报warning,日后再研究一下React18卸载组件的方法
        // ReactDOM.createRoot(document.getElementById('root')).unmount()
        // 所以用下17
        ReactDOM.unmountComponentAtNode(document.getElementById('root'))
    }

    return (
        <div>
            <h2>当前求和为:{count}</h2>
            <button onClick={add}>点击+1</button>
            <button onClick={unmount}>卸载组件</button>
        </div>
    )
}

GIF 2022-5-23 22-39-52.gif

Ref Hook

Ref Hook可以在函数组件中存储/查找组件内的标签或任意其它数据

  1. 语法: const refContainer = useRef()
  2. 作用:保存标签对象,功能与React.createRef()一样
import React from 'react'
import ReactDOM from 'react-dom'
export default function Demo() {
    const [count, setCount] = React.useState(0)

    const myRef = React.useRef()

    function show() {
        alert(myRef.current.value)
    }

    function add() {
        // setCount(count + 1) // 第一种写法
        setCount(count => count + 1) // 第二种写法
    }

    return (
        <div>
            <h2>当前求和为:{count}</h2>
            <button onClick={add}>点击+1</button>
            <input type="text" ref={myRef} />
        <button onClick={show}>提示数据</button>
        </div>
    )
}

GIF 2022-5-23 22-38-47.gif

Fragment

<Fragment></Fragment>可以传keychildren属性,<></>不允许传任何属性

像这样:

import React, { Component, Fragment } from 'react'

export default class Demo extends Component {
  render() {
    return (
      <Fragment>
          <input type="text" />
          <input type="text" />
      </Fragment>
    )
  }
}

image.png

Context

一种组件间通信方式, 常用于【祖组件】与【后代组件】间通信

在应用开发中一般不用context, 一般都用它的封装react插件

  1. 创建Context容器对象:const XxxContext = React.createContext()

  2. 渲染子组件时,外面包裹XxxContext.Provider, 通过value属性给后代组件传递数据:

    <xxxContext.Provider value={数据}>
    	子组件
    </xxxContext.Provider>
    
  3. 后代组件读取数据:

    1. //第一种方式:仅适用于类组件 
         static contextType = xxxContext  // 声明接收context
         this.context // 读取context中的value数据
    2. //第二种方式: 函数组件与类组件都可以
         <xxxContext.Consumer>
           {
             value => ( // value就是context中的value数据
               要显示的内容
             )
           }
         </xxxContext.Consumer>
    
import React, { Component } from 'react'
import './index.css'

// 创建用于保存用户名的Context对象
const UserNameContext = React.createContext()
const {Provider, Consumer} = UserNameContext

export default class Demo extends Component {

    state = {username: 'tom', age: 18}

    render() {
        const {username, age} = this.state
        return (
            <div className='com' style={{'width': '500px'}}>
                <h1>这是Demo组件</h1>
                <h2>用户名为:{username}</h2>
                <Provider value={{username, age}}>
                    <A />
                </Provider>
            </div>
        )
    }
}

class A extends Component {
    render() {
        return (
            <div className='com'>
                <h3>这是A组件</h3>
                <h4>不展示用户名</h4>
                <B />
            </div>
        )
    }
}

/* class B extends Component {
    // 需要Context就“举手” - 声明接收Context
    static contextType = UserNameContext
    render() {
        const {username, age} = this.context
        return (
            <div className='com'>
                <h3>这是B组件</h3>
                <h4>从Demo接收到的用户名为:{username},年龄为:{age}</h4>
            </div>
        )
    }
} */

function B() {
  return (
    <div className='com'>
        <h3>这是B组件</h3>
        <Consumer>
            {
                value => <h4>从Demo接收到的用户名为:{value.username},年龄为:{value.age}</h4>
            }
        </Consumer>
    </div>
  )
}

image.png

组件优化

Component的2个问题

  1. 只要执行setState(),即使不改变状态数据,组件也会重新render() => 效率低
  2. 只要前组件重新render(),就会自动重新render子组件,纵使子组件没有用到父组件的任何数据 => 效率低
  3. 原因:Component中的shouldComponentUpdate()总是返回true

效率高的做法

只有当组件的stateprops数据发生改变时才重新render()

  1. 重写shouldComponentUpdate()方法,比较新旧stateprops数据, 如果有变化才返回true,如果没有返回false

    import React, { Component } from 'react'
    
    export default class Parent extends Component {
    
        state = {carName: '奔驰'}
    
        changeCar = () => {
            this.setState({carName: '迈巴赫'})
        }
    
        shouldComponentUpdate(nextProps, nextState) {
            console.log(nextProps, nextState) // 接下来要变化的目标props和目标state
            console.log(this.props, this.state) // 目前的props和state
            if(JSON.stringify(this.state) === JSON.stringify(nextState)) {
                return false
            } return true
        }
    
        render() {
            console.log('parent--render')
            const {carName} = this.state
            return (
                <div style={{ 'width': '500px', 'backgroundColor': 'skyblue', 'padding': '10px' }}>
                    <h3>这是Parent组件</h3>
                    <span>车名字是: {carName}</span>
                    <br /><button onClick={this.changeCar}>点击换车</button>
                    <Child carName='宝马'/>
                </div>
            )
        }
    }
    
    class Child extends Component {
        shouldComponentUpdate(nextProps, nextState) {
            console.log(nextProps, nextState) // 接下来要变化的目标props和目标state
            console.log(this.props, this.state) // 目前的props和state
            if(JSON.stringify(this.props) === JSON.stringify(nextProps)) {
                return false
            } return true
        }
        render() {
            console.log('child--render')
            return (
                <div style={{ 'width': '100%', 'backgroundColor': 'orange', 'padding': '10px', 'marginTop': '20px' }}>
                    <h3>这是Child组件</h3>
                    <span>车名字是: {this.props.carName}</span>
                </div>
            )
        }
    }
    
  2. 使用PureComponentPureComponent重写了shouldComponentUpdate(), 只有stateprops数据有变化才返回true
    项目中一般使用PureComponent来优化

    import React, { PureComponent } from 'react'
    
    export default class Parent extends PureComponent {
    
        state = {carName: '奔驰'}
    
        changeCar = () => {
            this.setState({carName: '迈巴赫'})
        }
    
        render() {
            console.log('parent--render')
            const {carName} = this.state
            return (
                <div style={{ 'width': '500px', 'backgroundColor': 'skyblue', 'padding': '10px' }}>
                    <h3>这是Parent组件</h3>
                    <span>车名字是: {carName}</span>
                    <br /><button onClick={this.changeCar}>点击换车</button>
                    <Child carName='宝马'/>
                </div>
            )
        }
    }
    
    class Child extends PureComponent {
        render() {
            console.log('child--render')
            return (
                <div style={{ 'width': '100%', 'backgroundColor': 'orange', 'padding': '10px', 'marginTop': '20px' }}>
                    <h3>这是Child组件</h3>
                    <span>车名字是: {this.props.carName}</span>
                </div>
            )
        }
    }
    

    PureComponent只是进行stateprops数据的浅比较,如果只是数据对象内部数据变了, 返回false ,不要直接修改state数据, 而是要产生新数据
    image.png

render props

向组件内部动态传入带内容的结构(标签):

  1. Vue中:

    • 使用slot技术, 也就是通过组件标签体传入结构 <A><B/></A>
  2. React中:

    • 使用children props: 通过组件标签体传入结构

      import React, { Component } from 'react'
      
      export default class Parent extends Component {
          render() {
              return (
                  <div style={{ 'width': '500px', 'backgroundColor': 'skyblue', 'padding': '10px' }}>
                      <h3>这是Parent组件</h3>
                      <A><B/></A>
                  </div>
              )
          }
      }
      
      class A extends Component {
          state = {name: 'tom'}
          render() {
              console.log(this)
              const {name} = this.state
              return (
                  <div style={{ 'width': '100%', 'backgroundColor': 'orange', 'padding': '10px' }}>
                      <h3>这是A组件</h3>
                      {this.props.children}
                  </div>
              )
          }
      }
      
      class B extends Component {
          render() {
              console.log('render--B')
              return (
                  <div style={{ 'width': '100%', 'backgroundColor': 'rgb(79, 207, 93)', 'padding': '10px' }}>
                      <h3>这是B组件</h3>
                  </div>
              )
          }
      }
      

      image.png

    • 使用render props: 通过组件标签属性传入结构,而且可以携带数据,一般用render函数属性

      import React, { Component } from 'react'
      
      export default class Parent extends Component {
          render() {
              return (
                  <div style={{ 'width': '500px', 'backgroundColor': 'skyblue', 'padding': '10px' }}>
                      <h3>这是Parent组件</h3>
                      <A render={name => <B name={name}/>} />
                  </div>
              )
          }
      }
      
      class A extends Component {
          state = {name: 'tom'}
          render() {
              console.log(this)
              const {name} = this.state
              return (
                  <div style={{ 'width': '100%', 'backgroundColor': 'orange', 'padding': '10px' }}>
                      <h3>这是A组件</h3>
                      {this.props.render(name)}
                  </div>
              )
          }
      }
      
      class B extends Component {
          render() {
              console.log('render--B')
              return (
                  <div style={{ 'width': '100%', 'backgroundColor': 'rgb(79, 207, 93)', 'padding': '10px' }}>
                      <h3>这是B组件, {this.props.name}</h3>
                  </div>
              )
          }
      }
      

      image.png

错误边界

错误边界(Error boundary):用来捕获后代组件错误,渲染出备用页面,只使用于生产环境

只能捕获后代组件生命周期产生的错误,不能捕获自己组件产生的错误和其他组件在合成事件、定时器中产生的错误

import React, { Component } from 'react'
import Child from './Child'

export default class Parent extends Component {

    state = {
        hasError: '' // 用于标识子组件是否产生错误
    }

    // 当子组件出现报错时,会触发getDerivedStateFromError调用,并携带错误信息
    static getDerivedStateFromError(error) {
        console.log(error)
        return {hasError: error}
    }

    componentDidCatch(error, info) {
        console.log('统计错误次数,发送给后台') // 统计错误次数,反馈给服务器
    }

    render() {
        return (
            <div>
                <h2>这是Parent组件</h2>
                {this.state.hasError ? <h2>出现了点小问题...</h2> : <Child />}
            </div>
        )
    }
}

组件间通信方式总结

组件间的关系

  • 父子组件
  • 兄弟组件(非嵌套组件)
  • 祖孙组件(跨级组件)

几种通信方式

  1. props
    • children props
    • render props
  2. 消息订阅-发布
    • pub-subevent
  3. 集中式管理
    • reduxdva
  4. conText
    • 生产者-消费者模式

比较好的搭配方式

  • 父子组件:props
  • 兄弟组件:消息订阅-发布、集中式管理
  • 祖孙组件(跨级组件):消息订阅-发布、集中式管理、Context(开发用的少,封装插件用的多)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/129211.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录算法训练营第九天(字符串)| 28. 实现 strStr(),459.重复的子字符串

代码随想录算法训练营第九天&#xff08;字符串&#xff09;| 28. 实现 strStr()&#xff0c;459.重复的子字符串 28. 实现 strStr() 因为KMP算法很难&#xff0c;大家别奢求 一次就把kmp全理解了&#xff0c;大家刚学KMP一定会有各种各样的疑问&#xff0c;先留着&#xff0…

Qt编写雷达模拟仿真工具2-自定义QGraphicsItem按钮

一、前言 雷达模拟仿真工具&#xff0c;整体结构采用的QGraphicsView框架&#xff0c;场景需要设计一个可点击的自定义按钮出来&#xff0c;在QGraphicsView中一切基础元素点都是基于QGraphicsItem&#xff0c;在QGraphicsItem类中我们可以看到它不继承自QObject&#xff0c;那…

25万美金奖励章鱼加速器2022冬季获胜团队!

全长 1427 字&#xff0c;预计阅读 6 分钟 作者&#xff1a;MiX 2022年12月21日&#xff0c;章鱼加速器2022年冬季 Web3 创业营圆满落幕&#xff0c;61个入营项目中有5个脱颖而出&#xff0c;获得「章鱼未来之星」称号&#xff0c;排名不分先后&#xff0c;他们分别是&#xf…

第五章. 可视化数据分析图表—Seaborn图表(折线图,直方图,条形图,散点图)

第五章. 可视化数据分析图 5.7 Seaborn图表 Seaborn是一个基于Matplotlib的高级可视化效果库&#xff0c;偏向于统计图表&#xff0c;主要针对的是数据挖掘和机器学习中的变量特征选取&#xff0c;相比Matplotlib&#xff0c;他的语法相对简单&#xff0c;但是具有一定的局限性…

Windows下安装oracle19c

oracle 19c 不支持 Windows 7 和 Windows 8 以及 Windows Server 2008&#xff08;GetOverlappedResultEx function 函数不支持 win7&#xff09;&#xff0c;支持 Windows 8.1 以上及 Windows Server 2012 1.下载地址&#xff1a; https://www.oracle.com/database/technolo…

Gnoppix Linux 22.12 发布

导读基于 Kali Linux 的 Linux 滚动发行版 Gnoppix 22.12 带来了 GNOME 43、Linux 内核 6.0 和新的升级。作为传统的现场 CD 发行版 Knoppix 项目的继承者&#xff0c;Gnoppix Linux 是专门为渗透测试和反向工程而设计的。它为网页应用安全和数字权利保护进行了优化。除了对安全…

DNA甲基化重编程为红梨中光诱导的花青素生物合成提供了见解

期刊&#xff1a;Plant Science 影响因子&#xff1a;5.363 发表时间&#xff1a;2022 样本类型&#xff1a;果皮 客户单位&#xff1a;南京农业大学 凌恩生物客户南京农业大学吴俊团队发表在《Plant Science》上的文章“DNA methylatio…

【Ctfer训练计划】——(七)

作者名&#xff1a;Demo不是emo 主页面链接&#xff1a;主页传送门 创作初心&#xff1a;舞台再大&#xff0c;你不上台&#xff0c;永远是观众&#xff0c;没人会关心你努不努力&#xff0c;摔的痛不痛&#xff0c;他们只会看你最后站在什么位置&#xff0c;然后羡慕或鄙夷座…

【数据结构】LinkedList与链表

作者&#xff1a;✿✿ xxxflower. ✿✿ 博客主页&#xff1a;xxxflower的博客 专栏&#xff1a;【数据结构】篇 语录&#xff1a;⭐每一个不曾起舞的日子&#xff0c;都是对生命的辜负。⭐ 文章目录✿1.ArrayList的缺陷✿2.链表2.1链表的概念及结构2.2链表的模拟实现MySingleLi…

aws eks 集群container runtime升级容器管理工具的切换

参考资料 https://cloud-atlas.readthedocs.io/zh_CN/latest/kubernetes/debug/crictl.htmlhttps://zhuanlan.zhihu.com/p/562014518 container runtime Low-Level和High-Level容器运行时。runc、lxc、lmctfy、Docker&#xff08;容器&#xff09;、rkt、cri-o。每一个都是为…

springboot simple (12) springboot RabbitMQ

这里首先简单的介绍了RabbitMQ &#xff0c;然后实现了springboot集成RabbitMQ &#xff0c;包含两个工程&#xff1a; 1 Producer 生产者 2 Consumer 消费者 1 RabbitMQ 简介 AMQP &#xff1a;Advanced Message Queue&#xff0c;高级消息队列协议。 RabbitMQ 是一个由 Erl…

智能大屏兴起,酷开科技赋能营销战略!

随着科技的发展&#xff0c;智能大屏的功能与技术都在日新月异的快速更迭&#xff0c;年轻消费群体也对大尺寸智能大屏表现出了特别的偏爱&#xff0c;以前说到看视频、网上购物、阅读书籍时&#xff0c;人们第一时间就会想到手机&#xff0c;但随着智能大屏的出现&#xff0c;…

商用设计素材库,设计师必备。

免费、商用设计素材网站。 1、菜鸟图库 https://www.sucai999.com/?vNTYxMjky站内平面海报、UI设计、电商淘宝、免抠、高清图片、样机模板等素材非常齐全。还有在线抠图、CDR版本转换功能&#xff0c;能有效的为设计师节省找素材时间&#xff0c;提高工作效率。网站素材都能免…

LeetCode链表经典题目(二)

1. LeetCode203. 移除链表元素 2. LeetCode707.设计链表 3. LeetCode206. 反转链表 4. LeetCode24. 两两交换链表中的节点​ 5. LeetCode19. 删除链表的倒数第 N 个结点 6. LeetCode面试题 02.07. 链表相交 7. LeetCode142. 环形链表 II​ 1. LeetCode203. 移除链表元素 …

基于同豪的道路桥梁设计方案如何实现数字化交付(web发布)

0序&#xff1a; 当下有部分设计人员除了使用Revit、Microstation之外也使用过程的同豪软件进行道路桥梁的BIM建模。如何对同豪的BIM模型进行数字化交付呢&#xff1f; 1数据导出为FBX 具体导出过程可以参考&#xff1a; 数据的导出只要按步骤导出就行&#xff0c;非常简单…

2023最让人期待的日历!每个IT技术人必备

一转眼&#xff0c;2022年已经要接近尾声了..... 这一年的你过的怎么样呢&#xff1f;相比上一年的自己有什么变化呢&#xff1f; 凡是过往皆为序章&#xff0c;所有将来皆为可盼&#xff01;在2023年即将到来之际给大家推荐一本非常适合IT技术人的日历&#x1f449;「小滴日历…

python—you-get下载工具、wget下载工具

目录 wget you-get wget wget工具下载&#xff1a;GNU Wget 1.21.3 for Windows wget工具见&#xff1a;python-外部程序的调用os库、subprocess 模块_觅远的博客-CSDN博客_python外部库调用调出 you-get you-get是一款实用的网站视频下载工具。可以很轻松的下载到网络上…

极限学习机ELM回归预测(MATLAB代码实现)

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

【数据结构与算法】第十七篇:图论万字解析(进阶篇)

&#x1f440;作者简介&#xff1a;大家好&#xff0c;我是 快到碗里来~ &#x1f6a9;&#x1f6a9; 个人主页&#xff1a;快到碗里来~ 支持我&#xff1a;点赞关注~不迷路&#x1f9e1;&#x1f9e1;&#x1f9e1; ✔系列专栏&#xff1a;数据结构与算法⚡⚡⚡ (❁◡❁)励志格…

代码随想录算法训练营第十一天(栈与队列)| 20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值

代码随想录算法训练营第十一天&#xff08;栈与队列&#xff09;| 20. 有效的括号&#xff0c;1047. 删除字符串中的所有相邻重复项&#xff0c;150. 逆波兰表达式求值 20. 有效的括号 讲完了栈实现队列&#xff0c;队列实现栈&#xff0c;接下来就是栈的经典应用了。 大家先…