Web前端最全后端程序员入门react笔记(九)- react 插件使用(1),2024年最新武汉软通动力Web前端面试

最后

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

我们知道,在类里面我们使用ref1 = React.createRef();这种方式来定义ref,那么在function中,我们怎么定义ref呢,我们看一下

import React from 'react';
function App(){
    //定义ref
    const ref1=React.createRef();
    function getRef(){
        //获取ref的值
        console.log(ref1.current.value);
    }
    return (
        <div>
            <li><input type="text" ref={ref1}/></li>
            <button onClick={getRef}>getRef</button>
        </div>
    )
}
export default App;

Fragment

不知道大家有没有发现,当我们使用return的时候,必须返回一个标签,所有的jsx标签必须被一个标签包裹,像这种

    return (
        <div>
            <li><input type="text" ref={ref1}/></li>
            <button onClick={getRef}>getRef</button>
        </div>
    )

那么我有一个想法,我如果想让我的jsx标签不被包裹,应该怎么办?我觉得最简单的方法就是把标签去掉,比如这样

    return (
        <>
            <li><input type="text" ref={ref1}/></li>
            <button onClick={getRef}>getRef</button>
        </>
    )

但是空标签有一个问题,我们没办法给它赋值key,比如我们map遍历的时候,这个时候Fragment作用就出来了,它是一个可以被赋值key的空标签

import React, {Fragment} from 'react';
function App(){
    //定义ref
    const ref1=React.createRef();
    function getRef(){
        //获取ref的值
        console.log(ref1.current.value);
    }
    return (
        <Fragment key="1">
            <li><input type="text" ref={ref1}/></li>
            <button onClick={getRef}>getRef</button>
        </Fragment>
    )
}
export default App;

context

一般后端人员对context还是很熟悉的,一个上下文,贯穿整个请求,从进程,到各个子进程,都可能用到context的东西,那么前端,也提出了一个context的概念,用来实现组件和子组件的数据传递,我们举个例子

在组件中使用context

import React from 'react';
//定义全局的context对象
const MyContext=React.createContext();
//定义provider标签 类组件用
const Provider=MyContext.Provider;
//定义consumer标签 函数组件用
const Consumer=MyContext.Consumer;

//这是一个父组件
class App extends React.Component {
    //定义状态
    state = {
        name: 'React'
    }
  render() {

    return (
      <div className="App"  style={{padding: '10px',border: '1px solid red'}}>
        <h1>{this.state.name}</h1>
          {/\*父组件想要把上下文传递给子组件,必须使用context的Provider标签包裹,并把相关的值传递过去\*/}
          <Provider value={this.state}>
              <span><B></B></span>
          </Provider>

      </div>
    );
  }
}


class B extends React.Component {
    render() {
        return (
            <div className="App"  style={{padding: '10px',border: '1px solid red'}}>
                <h1>我是B</h1>
                <span ><C></C></span>
            </div>
        )
    }
}

class C extends React.Component {
    //谁想从全局context拿到 谁声明contexttype
    static contextType=MyContext;
    render() {
        return (
            <div className="App"  style={{padding: '10px',border: '1px solid red'}}>
                <h1>我是C</h1>
                {/\*这里取值渲染\*/}
                <h1>App组件穿过来的值是{this.context.name}</h1>
                <D></D>
            </div>
        )
    }
}

function D() {
    return (
        <div className="App"  style={{padding: '10px',border: '1px solid red'}}>
            <h1>我是Func D</h1>
            <Consumer>
                {value=>{
                    return <h1>App组件穿过来的值是{value.name}</h1>
                }}
            </Consumer>
        </div>
    );
}
export default App;

在这里插入图片描述

purgecomponent

我们之前使用redux的时候说过,redux只负责存储数据,如果我们想重新render,那么就得执行一个命令this.setstate={},相当于告诉react,说我更新了state,你需要重新render。其实呢,我们啥也没更新。既然我们啥都没更新,为什么还要执行render?我们能不能等到真正的state发生变化的时候再render?答案是可以,因为我们知道有一个生命周期函数,叫getSnapshotBeforeUpdate,我们可以通过对比state和props来判断返回true还是false,我们知道,既然getSnapshotBeforeUpdate是组件的生命周期函数,那么能不能让getSnapshotBeforeUpdate自动判断,而不是每次都是我手写判断呢?答案是可以,它是对component的优化,名字是React.PureComponent,我们来看看使用

import React from 'react';


//这是一个父组件
class App extends React.PureComponent {
    //定义状态
    state = {
        name: 'React'
    }
  render() {
      // 初始化render之后,由于数据不在变化,也不在重新render
      console.log('app.render');
      return (
      <div className="App"  style={{padding: '10px',border: '1px solid red'}}>
        <h1>{this.state.name}</h1>
          <button onClick={() => this.setState({name: 'vue'})}>更改状态名字</button>
          <B></B>
      </div>
    );
  }
}


class B extends React.PureComponent {
    // 初始化render一次之后,由于后续没有数据变化,故不再render
    render() {
        console.log('b.render');
        return (
            <div >
                <h1>我是B</h1>
                <span ></span>
            </div>
        )
    }
}


export default App;

children props

  • 一般我们写父子组件,可以通过嵌套来写
import React from 'react';
import "./App.css"
//这是一个父组件
class App extends React.PureComponent {
    //定义状态
    state = {
        name: 'React'
    }
    render() {
        return (
            <div className="component">
                <h1>我是App</h1>
                {/\*标签包裹的内容通过props.children获取\*/}
                <B x={100}>11211
                    <C></C>
                </B>
            </div>
        )
    }
}
class B extends React.PureComponent {
    // 初始化render一次之后,由于后续没有数据变化,故不再render
    render() {
        console.log(this.props);
        return (
            <div className="component">
                <h1>我是B</h1>
                {/\*获取组件内容\*/}
                <h1>组件内容:{this.props.children}</h1>
            </div>
        )
    }
}

class C extends React.PureComponent {
    render() {
        return (
            <div className="component">
                <h1>我是C组件:{this.props.name}</h1>
            </div>
        )
    }
}
export default App;

render props

  • 但是在实际开发中,可能多个人写多个组件,我们不可能实现这种链式嵌套,因为也可能会有这样的情况
    render() {
        return (
            <div>
                <h1>我是App</h1>
                {/\*app组件内,需要B和C的组合来实现功能\*/}
                <B>
                    <C></C>
                </B>
            </div>
        )
    }

那么这种情况我们应该怎么传递数据呢?这里,我们就用到了render props

import React from 'react';
import "./App.css"
//这是一个父组件
class App extends React.PureComponent {
    //定义状态
    state = {
        name: 'React'
    }
    render() {
        // name = this.state.name;
        return (
            <div className="component">
                <h1>我是App</h1>
                {/\*在App组件内 使用B组件嵌套c组件 并指定render接收的参数\*/}
                <B render={data=><C name={data} />} />

            </div>
        )
    }
}
class B extends React.PureComponent {
    // 初始化render一次之后,由于后续没有数据变化,故不再render
    render() {
        // console.log(this.props);
        return (
            <div className="component">
                <h1>我是B</h1>
                {/\*获取组件内容\*/}
                <h1>组件内容:{this.props.children}</h1>
                {/\*指定给c组件传递的参数\*/}
                {this.props.render("22233")}
            </div>
        )
    }
}

class C extends React.PureComponent {
    render() {
        console.log(this.props);
        return (
            <div className="component">
                {/\*打印b组件传递的参数\*/}
                <h1>我是C组件:{this.props.name}</h1>
            </div>
        )
    }
}
export default App;

错误边界

我们知道,一个页面可能是由很多个组件组成的,但是在开发的时候我们也发现了,一旦一个组件出现问题,整个页面都会报错,我们举个例子

import React from 'react';
import "./App.css"
//这是一个父组件
class App extends React.PureComponent {
    // state=[
    // {name:'张三'},
    // {name:'李四'},
    // ]
    //将state改成字符串
    state = "aaaa"
    render() {
        // name = this.state.name;
        return (
            <div className="component">
                <h1>我是App</h1>
                {/\*在App组件内 使用B组件嵌套c组件 并指定render接收的参数\*/}
                <B>{this.state}</B>
            </div>
        )
    }
}
class B extends React.PureComponent {
    render() {
        const persons = this.props.children;

        return (
            <div>
                <h2>我是b组件</h2>
                {persons.map((item,index)=>(<li key={index}>{item.name}</li>))}
            </div>
        )
    }
}
export default App;

在这里插入图片描述
那么问题来了,一个组件的错误,导致整个页面崩溃,这明显是不科学的。我们能不能有机制去捕捉组件的错误并做出对应的处理呢?就像try catch 这种模式,答案是有的。有两个方式来捕捉错误,getDerivedStateFromError捕捉错误通知react的组件,根据错误标识做出下一步处理。componentDidCatch可以做错误统计或者通知服务端错误详情

import React from 'react';
import "./App.css"

//这是一个父组件
class App extends React.PureComponent {
    // state=[
    // {name:'张三'},
    // {name:'李四'},
    // ]
    //将state改成字符串
    state = "aaaa"

    //捕捉子组件的错误信息 ,给state标识错误
    static getDerivedStateFromError(error) {

        return {
            hasError: true
        }
    }

    //用于通知服务端错误信息或者统计错误


### 最后

**前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档**

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)**

![](https://img-blog.csdnimg.cn/img_convert/0979ca4e1c5af02eb89ed7783f726ac6.webp?x-oss-process=image/format,png)

![](https://img-blog.csdnimg.cn/img_convert/6911bbd1ac3596b477c7bafaadca4482.webp?x-oss-process=image/format,png)



 = "aaaa"

    //捕捉子组件的错误信息 ,给state标识错误
    static getDerivedStateFromError(error) {

        return {
            hasError: true
        }
    }

    //用于通知服务端错误信息或者统计错误


### 最后

**前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档**

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)**

[外链图片转存中...(img-3V7ROYRq-1715887403431)]

[外链图片转存中...(img-9DKkq4fP-1715887403432)]



  • 16
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值