• React 组件


    类式组件

    可以温习下前置知识

    ES6 class 类_benlalagang的博客-CSDN博客ES6类的相关概念 constructor new extends super statichttps://blog.csdn.net/benlalagang/article/details/126358768?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166234173516782417012412%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=166234173516782417012412&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-2-126358768-null-null.nonecase&utm_term=%E7%B1%BB&spm=1018.2226.3001.4450

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>类式组件title>
    6. head>
    7. <body>
    8. <div id="app">div>
    9. <script src="js/react.development.js">script>
    10. <script src="js/react-dom.development.js">script>
    11. <script src="js/babel.min.js">script>
    12. <script type="text/babel"> // 此处一定要写babel
    13. // 创建函数式组件 首字母要大写
    14. class MyComponent extends React.Component{
    15. render(){
    16. // render是放在哪里的 MyComponent 的原型对象上。供实例使用
    17. console.log('render中的this:',this) // render里的this是 MYComponent的实例对象 === MYComponent组件实例对象
    18. return <h2>我是类定义的组件-适用于复杂组件的定义h2>
    19. }
    20. }
    21. // 渲染虚拟DOM到页面 函数定义的组件要写 闭合标签
    22. ReactDOM.render(<MyComponent/>,document.querySelector('#app'))
    23. script>
    24. body>
    25. html>
    1. 类式组件继承 extends React.Component
    2. 类里面的this 指向组件实例对象 === render里的this
    3. 类式组件拥有 props state refs  生命周期 等 

    定义类式组件 ReactDOM.render(,document.querySelector('#app')) 发生了什么 
      1.React解析组件标签,找到了MyComponent组件 
      2.发现组件是使用类定义的。随后new出来该类的实例,并通过该实例调用render方法 
      3.将render 返回的虚拟DOM 转化为真实DOM 随后呈现在页面中


    state(类似Vue组件里的data)

    组件的状态(数据) 直接定义到class 中 通过this.setState 方法修改 修改后自动render 更新页面

    1. class Weather extends React.Component{
    2. //初始化状态
    3. state = {isHot:false,wind:'微风'}
    4. render(){
    5. const {isHot,wind} = this.state
    6. return <h1 onClick={this.changeWeather}>今天天气很{isHot ? '炎热' : '凉爽'},{wind}h1>
    7. }
    8. //自定义方法————要用赋值语句的形式+箭头函数
    9. changeWeather = ()=>{
    10. const isHot = this.state.isHot
    11. this.setState({isHot:!isHot})
    12. }
    13. }
    14. //2.渲染组件到页面
    15. ReactDOM.render(<Weather/>,document.getElementById('test'))

    组件内的回调方法  都是用箭头函数 因为箭头函数this 指向上下文 ==》组件实例对象 可以正确的调用到各种方法  还可以获取到想要的 this.ref

    改变state的两种方式

     

    1. export default class Extension1 extends Component {
    2. state = {
    3. num:199
    4. }
    5. changeObj = () =>{
    6. this.setState({
    7. num:this.state.num - 8
    8. },() =>{
    9. console.log(this.state.num);
    10. })
    11. }
    12. // 第二个参数可以传入一个函数 在render之后才执行
    13. changeFun = () =>{
    14. this.setState( (state,props) => ({num:props.add * state.num}))
    15. }
    16. render() {
    17. const {num} = this.state
    18. return (
    19. <div>
    20. <h2>当前组件的数据是{num}h2>
    21. <button onClick={this.changeObj}>点击改变数据(对象方式)button>
    22. <button onClick={this.changeFun}>点击改变数据(函数方式)button>
    23. div>
    24. )
    25. }
    26. }

      (1). setState(stateChange, [callback])------对象式的setState

                1.stateChange为状态改变对象(该对象可以体现出状态的更改)

                2.callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用

             

      (2). setState(updater, [callback])------函数式的setState

                1.updater为返回stateChange对象的函数。

                2.updater可以接收到state和props。

                4.callback是可选的回调函数, 它在状态更新、界面也更新后(render调用后)才被调用。

    总结:

        1.对象式的setState是函数式的setState的简写方式(语法糖)

        2.使用原则:

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

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

            (3).如果需要在setState()执行后获取最新的状态数据,

              要在第二个callback函数中读取

    props(组件接收的数据)

    组件内部接收外部传来的数据  还可以进行 类型限制 默认值指定

    基本用法

    1. //创建组件
    2. class Person extends React.Component{
    3. render(){
    4. // console.log(this);
    5. const {name,age,sex} = this.props
    6. return (
    7. <ul>
    8. <li>姓名:{name}li>
    9. <li>性别:{sex}li>
    10. <li>年龄:{age+1}li>
    11. ul>
    12. )
    13. }
    14. }
    15. //渲染组件到页面
    16. ReactDOM.render(<Person name="jerry" age={19} sex="男"/>,document.getElementById('test1'))
    17. ReactDOM.render(<Person name="tom" age={18} sex="女"/>,document.getElementById('test2'))
    18. const p = {name:'老刘',age:18,sex:'女'}
    19. // console.log('@',...p);
    20. // ReactDOM.render(,document.getElementById('test3'))
    21. ReactDOM.render(<Person {...p}/>,document.getElementById('test3'))

    对类型和默认值进行限制

    需要引入专门支持的库  

        //对标签属性进行类型、必要性的限制

        Person.propTypes = {

          name:PropTypes.string.isRequired, //限制name必传,且为字符串

          sex:PropTypes.string,//限制sex为字符串

          age:PropTypes.number,//限制age为数值

          speak:PropTypes.func,//限制speak为函数

        }

        //指定默认标签属性值

        Person.defaultProps = {

          sex:'男',//sex默认值为男

          age:18 //age默认值为18

        }

    props接收 页面结构 (类似slot)

      }>

    1. class C extends PureComponent {
    2. render(){
    3. const ccc = 123
    4. return (
    5. <div className='child'>
    6. <p>以下是预留的插槽p>
    7. {this.props.render(ccc)}
    8. div>
    9. )
    10. }
    11. }
    12. class D extends PureComponent {
    13. render(){
    14. return (
    15. <div style={{background:'#f35'}}>
    16. <h3>我是D组件h3>
    17. {this.props.ccc}
    18. div>
    19. )
    20. }
    21. }

    refs (打标识 获取元素 一般用于输入类控件)

    字符串方式:

    1. //创建组件
    2. class Demo extends React.Component{
    3. //展示左侧输入框的数据
    4. showData = ()=>{
    5. const {input1} = this.refs
    6. alert(input1.value)
    7. }
    8. //展示右侧输入框的数据
    9. showData2 = ()=>{
    10. const {input2} = this.refs
    11. alert(input2.value)
    12. }
    13. render(){
    14. return(
    15. <div>
    16. <input ref="input1" type="text" placeholder="点击按钮提示数据"/> 
    17. <button onClick={this.showData}>点我提示左侧的数据button> 
    18. <input ref="input2" onBlur={this.showData2} type="text" placeholder="失去焦点提示数据"/>
    19. div>
    20. )
    21. }
    22. }
    23. //渲染组件到页面
    24. ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))

    回调函数形式的ref

    c 就是   currentNode   返回一个回调函数   currentNode(当前节点) 赋值给 this.xxx

    再在一些回调函数中 使用 this.xxx.value

    ref回调形式中 次数的问题 在更新中(改变状态重新render)会执行两次 第一次参数传入为null 为了清空  第二次才是 currentNode 通过将ref的回调函数 定义成class 绑定函数的方式 可以避免上述问题但大多数情况下 它是无关紧要的

    
    
    
      saveinput = (e) => {
        this.inputvalue = e
      }
      handleClick1 = () => {
        console.log(this.inputvalue.value);
      };
    1. //创建组件
    2. class Demo extends React.Component{
    3. //展示左侧输入框的数据
    4. showData = ()=>{
    5. const {input1} = this
    6. alert(input1.value)
    7. }
    8. //展示右侧输入框的数据
    9. showData2 = ()=>{
    10. const {input2} = this
    11. alert(input2.value)
    12. }
    13. render(){
    14. return(
    15. <div>
    16. <input ref={c => this.input1 = c } type="text" placeholder="点击按钮提示数据"/> 
    17. <button onClick={this.showData}>点我提示左侧的数据button> 
    18. <input onBlur={this.showData2} ref={c => this.input2 = c } type="text" placeholder="失去焦点提示数据"/> 
    19. div>
    20. )
    21. }
    22. }
    23. //渲染组件到页面
    24. ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))

     React.createRef() 方式 - 提前创建  专人专用

    1. //创建组件
    2. class Demo extends React.Component{
    3. /*
    4. React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专用”的
    5. */
    6. myRef = React.createRef()
    7. myRef2 = React.createRef()
    8. //展示左侧输入框的数据
    9. showData = ()=>{
    10. alert(this.myRef.current.value);
    11. }
    12. //展示右侧输入框的数据
    13. showData2 = ()=>{
    14. alert(this.myRef2.current.value);
    15. }
    16. render(){
    17. return(
    18. <div>
    19. <input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/> 
    20. <button onClick={this.showData}>点我提示左侧的数据button> 
    21. <input onBlur={this.showData2} ref={this.myRef2} type="text" placeholder="失去焦点提示数据"/> 
    22. div>
    23. )
    24. }
    25. }
    26. //渲染组件到页面
    27. ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))

    函数式组件

    1. //1.创建函数式组件
    2. function MyComponent(){
    3. console.log(this); //此处的this是undefined,因为babel编译后开启了严格模式
    4. return <h2>我是用函数定义的组件(适用于【简单组件】的定义)h2>
    5. }
    6. //2.渲染组件到页面
    7. ReactDOM.render(<MyComponent/>,document.getElementById('test'))

    执行了ReactDOM.render(.......之后,发生了什么?

    1.React解析组件标签,找到了MyComponent组件。

    2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现在页面中。

    普通函数内部/箭头函数的this以及 call bind apply的用法_benlalagang的博客-CSDN博客函数内this的指向。和call() apply() bind() 方法小介绍https://blog.csdn.net/benlalagang/article/details/126011629?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166234698416781790746959%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=166234698416781790746959&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-126011629-null-null.nonecase&utm_term=this&spm=1018.2226.3001.4450

    因为函数式组件没有自己的this 所以它不能使用 state 和 refs

    可以正常接收props

    1. function Person (props){
    2. const {name,age,sex} = props
    3. return (
    4. <ul>
    5. <li>姓名:{name}li>
    6. <li>性别:{sex}li>
    7. <li>年龄:{age}li>
    8. ul>
    9. )
    10. }
    11. Person.propTypes = {
    12. name:PropTypes.string.isRequired, //限制name必传,且为字符串
    13. sex:PropTypes.string,//限制sex为字符串
    14. age:PropTypes.number,//限制age为数值
    15. }
    16. //指定默认标签属性值
    17. Person.defaultProps = {
    18. sex:'男',//sex默认值为男
    19. age:18 //age默认值为18
    20. }
    21. //渲染组件到页面
    22. ReactDOM.render(<Person name="jerry"/>,document.getElementById('test1'))

     通过Hooks 让函数组件可以使用 state 、 生命周期 refs  路由等....

    (1). State Hook: React.useState()

    (2). Effect Hook: React.useEffect()

    (3). Ref Hook: React.useRef()

  • 相关阅读:
    Java-自定义LinkedList类
    【Delphi】FMX Form的BorderStyles不同平台说明
    ServletContext
    电影兑换券的推荐策略——二分图最优匹配算法
    m序列生成器的Matlab实现
    链表|707.设计链表
    Linux网络流量监控iftop
    AIGC笔记--Maya提取和修改FBX动作文件
    蓝桥杯每日一题2023.10.14
    初识OpenGL (-)VAO顶点数组对象
  • 原文地址:https://blog.csdn.net/benlalagang/article/details/126698635