React基础

2023-05-16

#####1. Context全局值
链接地址
链接地址
目的是为了避免一些外部的传参向下传递时需要通过一层层的组件

// defaultValue只有在找不到附近的Provider时才会起作用
const ThemeContext = React.createContext(defaultValue)

function Test(){
	return (
		<ThemeContext.Provider value={value}>
			<ToolBar />
		</ThemeContext.Provider>
	)
}

类组件可以通过this.context来在子组件中获取context的值,也就是通过value传入的值
而在函数组件中因为不存在this,所以可以使用consumer或者useContext来获取
// 底层组件 - 函数是组件
import {ThemeContext} from './theme-context'

function ThemeLink (props) {
    // const theme = this.context // 会报错。函数式组件没有实例,即没有 this

    // 函数式组件可以使用 Consumer
    // return <ThemeContext.Consumer>
    //     { value => <p>link's theme is {value}</p> }
    // </ThemeContext.Consumer>

    // 函数组件引入context也是可以的,那就意味这两种消费方式都可以
    const theme = useContext(ThemeContext);
    return <p>link's theme333333 is {theme}</p>
}
2. Refs转发

链接地址
对于一些可重复使用的组件库来说,想要操作组件的真实dom值,可以通过这种方式

// 第二个参数 ref 只在使用 React.forwardRef 定义组件时存在。常规函数和 class 组件不接收 ref 参数,且 props 中也不存在 ref。
// 类组件中,可以使用React.createRef()来创建
const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

// 你可以直接获取 DOM button 的 ref:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

// 函数组件中,可以使用useRef的hook来创建
import React, {useRef} from 'react';

const ref = useRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

Refs转发和高阶组件结合(晚上具体看一下)
链接地址

3. 高阶组件HOC

强化props , 控制渲染 ,赋能组件
链接地址

  1. 老版本包装组件的方式:mixin
    只能通过createClass包装,类似于Vue中的mixin
const customMixin = {
  componentDidMount(){
    console.log( '------componentDidMount------' )
  },
  say(){
    console.log(this.state.name)
  }
}

const APP = React.createClass({
  mixins: [ customMixin ],
  getInitialState(){
    return {
      name:'alien'
    }
  },
  render(){
    const { name  } = this.state
    return <div> hello ,world , my name is { name } </div>
  }
})

引入的问题:
1.不同mixins之间可能会有先后顺序甚至代码冲突覆盖的问题
2.会导致代码滚雪球式的复杂程度
// 高阶组件——动态渲染

function renderHOC(WrapComponent){
  return class Index  extends React.Component{
      constructor(props){
        super(props)
        this.state={ visible:true }  
      }
      setVisible(){
         this.setState({ visible:!this.state.visible })
      }
      render(){
         const {  visible } = this.state 
         return <div className="box"  >
           <button onClick={ this.setVisible.bind(this) } > 挂载组件 </button>
           { visible ? <WrapComponent { ...this.props } setVisible={ this.setVisible.bind(this) }   />  : <div className="icon" ><SyncOutlined spin  className="theicon"  /></div> }
         </div>
      }
  }
}

class Index extends React.Component{
  render(){
    const { setVisible } = this.props
    return <div className="box" >
        <p>hello,my name is alien</p>
        <img  src='https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=294206908,2427609994&fm=26&gp=0.jpg'   /> 
        <button onClick={() => setVisible()}  > 卸载当前组件 </button>
    </div>
  }
}
export default renderHOC(Index)

路由懒加载(异步组件(懒加载))

/* 路由懒加载HOC */
export default function AsyncRouter(loadRouter) {
  return class Content extends React.Component {
    state = {Component: null}
    componentDidMount() {
      if (this.state.Component) return
      loadRouter()
        .then(module => module.default)
        .then(Component => this.setState({Component},
         ))
    }
    render() {
      const {Component} = this.state
      return Component ? <Component {
      ...this.props
      }
      /> : null
    }
  }
}

const Index = AsyncRouter(()=>import('../pages/index'))

性能优化(节流)
useMemo和useCallback更多的使用场景应该是对于子组件渲染的优化
区别在于:
useMemo缓存的是回调函数执行后return的返回值,而useCallback缓存的是回调函数本身。
链接地址

function HOC (Component){
     return function renderWrapComponent(props){
       const { num } = props
       const RenderElement = useMemo(() =>  <Component {...props}  /> ,[ num ])
       return RenderElement
     }
}
class Index extends React.Component{
  render(){
     console.log(`当前组件是否渲染`,this.props)
     return <div>hello,world, my name is alien </div>
  }
}
const IndexHoc = HOC(Index)

export default ()=> {
    const [ num ,setNumber ] = useState(0)
    const [ num1 ,setNumber1 ] = useState(0)
    const [ num2 ,setNumber2 ] = useState(0)
    return <div>
        <IndexHoc  num={ num } num1={num1} num2={ num2 }  />
        <button onClick={() => setNumber(num + 1) } >num++</button>
        <button onClick={() => setNumber1(num1 + 1) } >num1++</button>
        <button onClick={() => setNumber2(num2 + 1) } >num2++</button>
    </div>


不要在 render 方法中使用 HOC
React 的 diff 算法(称为协调)使用组件标识来确定它是应该更新现有子树还是将其丢弃并挂载新子树。 如果从 render 返回的组件与前一个渲染中的组件相同(===),则 React 通过将子树与新子树进行区分来递归更新子树。 如果它们不相等,则完全卸载前一个子树。

虽然高阶组件的约定是将所有 props 传递给被包装组件,但这对于 refs 并不适用。那是因为 ref 实际上并不是一个 prop - 就像 key 一样,它是由 React 专门处理的。如果将 ref 添加到 HOC 的返回组件中,则 ref 引用指向容器组件,而不是被包装组件。




##### 4. Fragments
用于返回多个元素
```javascript
render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

// 简洁用法
render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}
5. 深入JSX

在 JSX 类型中使用点语法

import React from 'react';

const MyComponents = {
  DatePicker: function DatePicker(props) {
    return <div>Imagine a {props.color} datepicker here.</div>;
  }
}

function BlueDatePicker() {
  return <MyComponents.DatePicker color="blue" />;
}

实际上,JSX 仅仅只是 React.createElement(component, props, …children) 函数的语法糖

// JSX
function Test(){
	return (
		<>
			<div>1111</div>
		</>
	)
}

// Babel
function hello() {
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", null, "111"));
}

React.createElement(
  type,
  [props],
  [...children]
)
第一个参数是必填,传入的是似HTML标签名称,eg: ul, li
第二个参数是选填,表示的是属性,eg: className
第三个参数是选填, 子节点,eg: 要显示的文本内容

function hello() {
  return (
  	<>
    	<div className="test" style={{width: '100px'}}>111</div>
    </>
  );
}

function hello() {
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
    className: "test",
    style: {
      width: '100px'
    }
  }, "111"));
}


function hello() {
  return <div>
  			<Hello value={'string'}></Hello>
  		</div>;
}

function hello() {
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Hello, {
    value: 'string'
  }));
}



// 添加了逻辑与发的JSX
function hello() {
  return (
  	<div>
      {isFlag ? 'hello' : <Hello>{11111}</Hello>}
    </div>
  )
}

function hello() {
  return /*#__PURE__*/React.createElement("div", null, isFlag ? 'hello' : /*#__PURE__*/React.createElement(Hello, null, 11111));
}

&&运算符

{1 && 2}  // 2
{0 && 2} // 0
{3 && 2} // 2
{-1 && 2} // 2
{'' && 2} // 不会被渲染
{'1' && 2}

1.两边条件都为true时,结果才为true2.如果有一个为false,结果就为false3.当第一个条件为false时,就不再判断后面的条件

注意:当数值参与逻辑与运算时,结果为true,那么会返回的会是第二个为真的值;如果结果为false,返回的会是第一个为假的值。

||运算符

2.1只要有一个条件为true时,结果就为true;
2.2当两个条件都为false时,结果才为false;
2.3当一个条件为true时,后面的条件不再判断

注意:当数值参与逻辑或运算时,结果为true,会返回第一个为真的值;如果结果为false,会返回第二个为假的值;

??=逻辑空赋值
逻辑空赋值运算符 (x ??= y) 仅在 x 是 nullish (null 或 undefined) 时对其赋值。

const a = { duration: 50 };

a.duration ??= 10;
console.log(a.duration);
// expected output: 50

a.speed ??= 25;
console.log(a.speed);
// expected output: 25
6. Portals
7. 自定义Hooks

不要在循环,条件或嵌套函数中调用 Hook, 确保总是在你的 React 函数的最顶层调用他们。遵守这条规则,你就能确保 Hook 在每一次渲染中都按照同样的顺序被调用。这让 React 能够在多次的 useState 和 useEffect 调用之间保持 hook 状态的正确。
https://react.docschina.org/docs/hooks-rules.html#explanation


8. 组件的生命周期

链接地址
生命周期示例

渲染部分:
废除了静态方法 static getDerivedStateFromProps()
(会在组件渲染,state或props改变时触发,在render()方法前,且获取不到组件实例)

更新部分:
废除了 shouldComponentUpdate()
(会在组件更新的render()方法前触发,第一次渲染不会触发,且返回false依旧可能导致组件重新渲染)

9. 事件处理,合成事件

https://react.docschina.org/docs/handling-events.html

在 React 中另一个不同点是你不能通过返回 false 的方式阻止默认行为。你必须显式的使用 preventDefault。在这里,e 是一个合成事件(SyntheticEvent 实例将被传递给你的事件处理函数,它是浏览器的原生事件的跨浏览器包装器。除兼容所有浏览器外,它还拥有和浏览器原生事件相同的接口,包括 stopPropagation() 和 preventDefault(),如果因为某些原因,当你需要使用浏览器的底层事件时,只需要使用 nativeEvent 属性来获取即可。)。

boolean bubbles
boolean cancelable
DOMEventTarget currentTarget
boolean defaultPrevented
number eventPhase
boolean isTrusted
DOMEvent nativeEvent
void preventDefault()
boolean isDefaultPrevented()
void stopPropagation()
boolean isPropagationStopped()
void persist()
DOMEventTarget target
number timeStamp
string type
function Form() {
  function handleSubmit(e) {
    e.preventDefault();
    console.log('You clicked submit.');
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}
10. key值

数组元素中使用的 key 在其兄弟节点之间应该是独一无二的。然而,它们不需要是全局唯一的。当我们生成两个不同的数组时,我们可以使用相同的 key 值。

key 会传递信息给 React ,但不会传递给你的组件。如果你的组件中需要使用 key 属性的值,请用其他属性名显式传递这个值:

const content = posts.map((post) =>
  <Post
    key={post.id}
    id={post.id}
    title={post.title} />
);
11. vue中的diff算法

链接地址

  1. 虚拟DOM
    通过JS来创建一个模拟真实DOM的数据结构
// 真实的dom结构
<ul id='list'>
    <li class='item1'>111</li>
    <li class='item2'>222</li>
    <li class='item3'>333</li>
</ul>

// 旧的虚拟dom结构
const oldVDom = { 
     tagName: 'ul', // 标签名
     props: {  // 标签属性
        id: 'list' 
     },
     children: [ // 标签子节点
        { tagName: 'li', props: { class: 'item1' }, children: ['111'] },
        { tagName: 'li', props: { class: 'item2' }, children: ['222'] },
        { tagName: 'li', props: { class: 'item3' }, children: ['333'] },
     ]
}

对于浏览器的渲染过程而言,触发一次重排的渲染代价还是挺大的,如果在短时间内多次触发,那么很可能会导致页面出现元素加载不出来或白屏的情况。

虚拟DOM的缺点

  1. 首屏加载时间较长
    因为需要在渲染真实DOM前通过JS模拟生成虚拟DOM结构,所以在首次加载时这一部分时间也需要算上
  2. 在一些极端场景下,虚拟DOM并不是最优解
    如果一个页面的所有元素都被改变了,那么实际上这种情况下,直接刷新DOM相比于虚拟DOM的更新而言是一个更优的方式。

Diff算法规则:

  1. 同层比较:
    如果不同层比较的话,全部的对比完一整个dom结构,时间复杂度是 O(n^3),而同层比较的时间复杂度是 O(n),虽然牺牲了一定的精度但是提高了效率。

diff算法遵循深度优先遍历(DFS)的原则,然后通过将遍历节点与其新的虚拟DOM结构进行同层比较
(深度优先遍历:栈结构,广度优先遍历:队列结构)

节点类型改变:此时diff的过程中旧节点会被直接销毁,然后挂载新的节点,同时旧节点的子节点也会被全部销毁。

节点类型一样,属性或者属性值发生变化:不会触发节点的挂载和卸载,只会触发当前节点的更新。

删除/新增/改变 节点:这时候就需要找出这些节点并在newVDom中进行插入/删除,这个过程请看下面vue和react是如何利用key值来处理的吧。

文本变化:只会更新该节点的文本信息。

12. fiber

https://zhuanlan.zhihu.com/p/26027085
React Fiber一个更新过程被分为两个阶段(Phase):第一个阶段Reconciliation Phase和第二阶段Commit Phase。

在第一阶段Reconciliation Phase,React Fiber会找出需要更新哪些DOM,这个阶段是可以被打断的;但是到了第二阶段Commit Phase,那就一鼓作气把DOM更新完,绝不会被打断。

以render函数为界,第一阶段可能会调用下面这些生命周期函数,说是“可能会调用”是因为不同生命周期调用的函数不同。

componentWillMount
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate

下面这些生命周期函数则会在第二阶段调用。

componentDidMount
componentDidUpdate
componentWillUnmount

在现有的React中,每个生命周期函数在一个加载或者更新过程中绝对只会被调用一次;在React Fiber中,不再是这样了,第一阶段中的生命周期函数在一次加载和更新过程中可能会被多次调用!

render多调用会影响性能,react优化大多都是从避免不必要的render为思路进行优化。

严格说来,render函数本身的执行不是很豪耗性能,毕竟render只是一个无副作用的纯函数,但是执行render必会根据返回结果去做Virtual DOM比对甚至修改DOM,这才是耗性能的部分;用shouldComponenntUpdate可以避免不必要的render,但也只是避免“不必要的render”,对于必要的render,React Fiber就有作用了。

14. react触发组件渲染的时机

1 state的改动
在类组件中,是通过this.setState()来完成的
在函数组件中通过useState()的hooks来完成的
2. 组件的props
组件的props 改变了,不一定触发 render 函数的执行,但是如果 props 的值来自于父组件或者祖先组件的 state
3. this.forceUpdate()

注意: <button onClick={() => this.forceUpdate()}>强制渲染 不可以写为<button onClick={this.forceUpdate}>强制渲染</button>

在这种情况下,父组件或者祖先组件的 state 发生了改变,就会导致子组件的重新渲染

15. 怎样可以实现控制子组件的渲染

可以使用HOC,并且通过useMemo或useCallback来包裹
链接地址

function HOC (Component){
     return function renderWrapComponent(props){
       const { num } = props
       const RenderElement = useMemo(() =>  <Component {...props}  /> ,[ num ])
       return RenderElement
     }
}
16. 虚拟DOM

虚拟DOM

// 一个基本的html
<div id="app">
  <p class="text">hello world!!!</p>
</div>

// 虚拟DOM的转化
{
  tag: 'div',
  props: {
    id: 'app'
  },
  chidren: [
    {
      tag: 'p',
      props: {
        className: 'text'
      },
      chidren: [
        'hello world!!!'
      ]
    }
  ]
}

17. diff算法

diff算法

18. React.lazy()和 Suspence

https://www.cnblogs.com/forcheng/p/13132582.html

import React, { Suspense } from 'react';

const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <OtherComponent />
      </Suspense>
    </div>
  );
}


// 实现
export function lazy<T, R>(ctor: () => Thenable<T, R>): LazyComponent<T> {
  let lazyType = {
    $$typeof: REACT_LAZY_TYPE,
    _ctor: ctor,
    // React uses these fields to store the result.
    _status: -1,
    _result: null,
  };

  return lazyType;
}


export function readLazyComponentType<T>(lazyComponent: LazyComponent<T>): T {
  const status = lazyComponent._status;
  const result = lazyComponent._result;
  switch (status) {
    case Resolved: {
      const Component: T = result;
      return Component;
    }
    case Rejected: {
      const error: mixed = result;
      throw error;
    }
    case Pending: {
      const thenable: Thenable<T, mixed> = result;
      throw thenable;
    }
    default: { // lazyComponent 首次被渲染
      lazyComponent._status = Pending;
      const ctor = lazyComponent._ctor;
      const thenable = ctor();
      thenable.then(
        moduleObject => {
          if (lazyComponent._status === Pending) {
            const defaultExport = moduleObject.default;
            lazyComponent._status = Resolved;
            lazyComponent._result = defaultExport;
          }
        },
        error => {
          if (lazyComponent._status === Pending) {
            lazyComponent._status = Rejected;
            lazyComponent._result = error;
          }
        },
      );
      // Handle synchronous thenables.
      switch (lazyComponent._status) {
        case Resolved:
          return lazyComponent._result;
        case Rejected:
          throw lazyComponent._result;
      }
      lazyComponent._result = thenable;
      throw thenable;
    }
  }
}

Suspence
React 16 将提供一个内置函数 componentDidCatch,如果 render() 函数抛出错误,该函数可以捕捉到错误信息,并且可以展示相应的错误信息,这个方法真的很赞!

React 捕获到异常之后,会判断异常是不是一个 thenable,如果是则会找到 SuspenseComponent ,如果 thenable 处于 pending 状态,则会将其 children 都渲染成 fallback 的值,一旦 thenable 被 resolve 则 SuspenseComponent 的子组件会重新渲染一次。


class Suspense extends React.Component {
  state = {
    promise: null
  }

当有错误发生时, 我们可以友好地展示 fallback 组件;
可以捕捉到它的子元素(包括嵌套子元素)抛出的异常;
可以复用错误组件;

  componentDidCatch(err) {
    // 判断 err 是否是 thenable
    if (err !== null && typeof err === 'object' && typeof err.then === 'function') {
      this.setState({ promise: err }, () => {
        err.then(() => {
          this.setState({
            promise: null
          })
        })
      })
    }
  }

  render() {
    const { fallback, children } = this.props
    const { promise } = this.state
    return <>{ promise ? fallback : children }</>
  }
}
19. import()

可以理解为webpack如何实现动态加载模块
https://www.cnblogs.com/forcheng/p/13132582.html

import()实际上返回的是一个Promise对象,并且通过创建script标签来实现对应模块的加载
由 import() 返回的 Promise 的完成态是一个模块命名空间对象

function import(url) {
  return new Promise((resolve, reject) => {
    const script = document.createElement("script");
    const tempGlobal = "__tempModuleLoadingVariable" + Math.random().toString(32).substring(2);
    script.type = "module";
    script.textContent = `import * as m from "${url}"; window.${tempGlobal} = m;`;

    script.onload = () => {
      resolve(window[tempGlobal]);
      delete window[tempGlobal];
      script.remove();
    };

    script.onerror = () => {
      reject(new Error("Failed to load module script with URL " + url));
      delete window[tempGlobal];
      script.remove();
    };

    document.documentElement.appendChild(script);
  });
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React基础 的相关文章

随机推荐

  • MQ2烟雾传感器

    1 MQ 2气体传感器所使用的气敏材料是在清洁空气中电导率较低的二氧化锡 SnO2 当传感器所处环境中存在可燃气体时 xff0c 传感器的电导率随空气中可燃气体浓度的增加而增大 使用简单的电路即可将电导率的变化转换为与该气体浓度相对应的输出
  • alembic

    alembic是sqlalchemy的作者开发的 用来做ORM模型与数据库的迁移与映射 alembic使用方式跟git有点了类似 xff0c 表现在两个方面 xff0c 第一个 xff0c alembic的所有命令都是以alembic开头
  • VScode远程免密登录

    安装配置python环境 xff1a 用VScode配置Python开发环境 xiaoj wang 博客园 cnblogs com VScode免密登录远程服务器 VS code ssh免密登陆 1 xff09 windows 下 xff0
  • linux虚拟机和主机能相互ping通,linux却不能访问外网

    linux虚拟机和主机能相互ping通 xff0c linux却不能访问外网 下面是试错过程 修改ifcfg eth0 xff08 名字可能不一样 xff09 vi etc sysconfig network scripts ifcfg e
  • 树莓派:树莓派的各个引脚

    由于第一次接触树莓派 xff0c xff0c xff0c emmmm xff0c 仔细写 xff0c 奥里给 3 3V 5V xff08 VCC xff09 xff1a 显然是电源正极啦 GND xff1a 接地用 xff0c 负极负极负极
  • 不分类工具:sd卡格式化工具安装教程

    下载地址 xff1a https www sdcard org downloads formatter 4 eula windows 进入上面这个链接 xff0c 你会看到满上面都是字 xff0c 有一个download xff0c 点完还
  • 不分类工具:Win32 DiskImager安装教程

    下载地址 xff1a http sourceforge net projects win32diskimager 这个也是很普普通通的下载安装 1 直接 download 2 双击安装文件 xff0c 弹出如下框 xff0c 选择我同意 x
  • Meta-Learning: Learning to Learn Fast

    Meta Learning Learning to Learn Fast 元学习 学习如何学习 译 原文 本文与原文基本没有区别 xff0c 仅供个人学习记录 电子笔记本 前言 xff1a 元学习解决 xff1a 遇到没有见过的任务 xff
  • 解决 Docker 容器时间与本地时间不一致的问题

    Linux 通过 Date 命令查看系统时间 xff0c 得到如下结果 xff1a root 64 iZ8vbg6m7f5ntzibw3t4huZ date Mon Aug 26 12 24 58 CST 2019 但是在 Docker 容
  • 记录ssh 和vnc命令

    ssh windows是客户端 linux是服务端 在windows powershell 输入 ssh rikirobot 64 192 168 x xxx xff08 ip地址 xff09 VNC Viewer 参考文章 xff1a 1
  • Redux源码解析(部分)

    相信用过React的小伙伴对于Redux一定不陌生 xff0c A Predictable State Container for JS Apps xff0c 这是官方文档对于Redux的定义 xff0c 即一款适用于JS Apps的可预测
  • Axios源码解析(部分)

    从 Github 上把 Axios 项目的 master 分支拷贝到本地 xff0c 用编辑器打开项目目录 首先我们先解析一下整个 Axios 项目的一些关键的文件结构 对照项目的文件目录 xff0c 梳理一下其中的一些关键文件夹以及它的作
  • 解析Javacript的事件循环机制

    前言 作为最受欢迎的Web编程语言 xff0c Javascript的单线程执行是其一大特点 xff0c 也就是说在同一时间只能有一个任务处于执行状态 xff0c 而后续的任务需要等待当前任务处理完毕后才能继续处理 xff0c 而在当前编程
  • 关于项目打包相关的优化问题

    本文主要是针对项目在打包过程中使用的一些Webpack相关的打包手段 1 首先在真正处理我们的打包之前 xff0c 我们可以通过安装插件来具体查看一下我们目前项目中的打包模块以及打包时间 打包后各个模块的可视化工具 webpack bund
  • 英语词汇、短语、语句积累

    rules of thumb 经验法则
  • 关于Webpack plugins插件的两种写法

    类写法以及require方式引入 span class token keyword class span span class token class name HelloWorld span span class token punctu
  • 关于mini-css-extract-plugin在使用过程中出现冲突的问题

    今天在优化打包的过程中 xff0c 运行npm run build后 xff0c 总是会出现冲突的警告信息 xff0c 而且对于我的这个项目而言出现了几十条的冲突提示 如下 问题排查 首先我以为可能是由于我新引入的优化方面的插件导致了原先的
  • 关于使用Antd中的DatePicker出现的日期格式转化问题(Dayjs和Momentjs)

    在测试过程中发现了一个比较有意思的bug问题 xff0c 我们使用的是antd中的DatePicker组件 xff0c 当时间选择框存在已经设定的初始值后 xff0c 点击时间选择框直接报错 xff0c 但是当清除内容或者处于新建没有默认值
  • Javascript基础知识整理—1

    1 JS数据类型 原始数据类型 xff1a boolean xff0c string xff0c null xff0c undefined xff0c symbol xff0c bigint xff0c number 引用类型 xff1a
  • React基础

    1 Context全局值 链接地址 链接地址 目的是为了避免一些外部的传参向下传递时需要通过一层层的组件 span class token comment defaultValue只有在找不到附近的Provider时才会起作用 span s