React高级指引(上)

无障碍辅助功能

无障碍辅助功能是使得辅助技术正确解读网页的必要条件
可以从以下几个方面考虑设计:语义化的HTML、无障碍的表单、控制焦点、鼠标和指针事件、语言、文档标题、色彩对比度等

代码分割

对应用进行代码分割能够“懒加载”当前用户所需要的内容,能够显著地提高应用性能。尽管并没有减少应用整体的代码体积,但避免加载用户永远不需要的代码,在初始加载的时候减少所需加载的代码量。

  1. import()
  2. React.lazy

有关React.lazy: React.lazy 和 Suspense 技术还不支持服务端渲染。如果想要在使用服务端渲染的应用中使用,可以使用 Loadable Components 这个库。 React.lazy 接受一个函数,这个函数需要动态调用 import()。它必须返回一个 Promise,该 Promise 需要 resolve 一个 default export 的 React 组件。然后应在 Suspense 组件中渲染 lazy 组件,如此使得我们可以使用在等待加载 lazy 组件时做优雅降级(如 loading 指示器等)fallback 属性接受任何在组件加载过程中你想展示的 React 元素。你可以将 Suspense 组件置于懒加载组件之上的任何位置。你甚至可以用一个 Suspense 组件包裹多个懒加载组件。

show you the code

import React , { Suspense } from 'react';

const PageTitle = React.lazy(()=>import('./components/pageTitle'))
const Left = 

function MyComp(){
  return(
    Loading}>
      
    
  )
}

错误边界

在子组件树的任何位置捕获 JavaScript 错误,记录这些错误,并显示一个备用 UI ,而不是使整个组件树崩溃
Tips:

  • 只有class组件才能成为错误边界组件
  • 错误边界无法捕获以下场景中产生的错误:

    1. 事件处理,若想在事件处理器内部捕获错误,可使用普通的 JavaScript try / catch 语句
    2. 异步代码(例如 setTimeout 或 requestAnimationFrame 回调函数)
    3. 服务端渲染
    4. 它自身抛出来的错误(并非它的子组件)
  • 如果一个错误边界无法渲染错误信息,则错误会冒泡至最近的上层错误边界,这也类似于 JavaScript 中 catch {} 的工作机制。

show you the code

// 未添加错误边界

function App(){
return (
    

正常展示的内容

); } function MyComp(){ return(
{ Math.random() > 0.2 ? new Error('自定义错误!!!') : '没有错误'}
) }

此时子组件报错,导致整个页面crash
React高级指引(上)_第1张图片

// 添加错误边界后的代码

function App(){
return (
    

正常展示的内容

); } function MyComp(){ return(
{ Math.random() > 0.2 ? new Error('自定义错误!!!') : '没有错误'}
) } class MyErrorBoundary extends React.Component{ constructor(props:any){ super(props) this.state = { hasError : false} } static getDerivedStateFromError(){ return { hasError : true} } componentDidCatch(error,info){ console.error(error,info); } render(){ if(this.state.hasError){ return(

Oops,there's something wrong

) }else{ return this.props.children } } }

此时子组件报错,整个页面未crash
React高级指引(上)_第2张图片

anyway,错误边界的粒度由你来决定,可以将其包装在最顶层的路由组件并为用户展示一个 “Something went wrong” 的错误信息,就像服务端框架经常处理崩溃一样。你也可以将单独的部件包装在错误边界以保护应用其他部分不崩溃。

Context

无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法,但如果你只是想避免层层传递一些属性,组件组合有时候是一个比 context 更好的解决方案:将组件自身作为属性传下去

动态Context的实例:

const myContext = createContext(null)

function MyComp(){
  const [theme,setTheme] = useState('dark')
  const themes = {
    theme,
    onThemeChange:setTheme
  };
  return(
    
      
    
  )
}

function ThemeInput(){
  const themeStatus = useContext(myContext)
  const {theme, onThemeChange} = themeStatus
  return (
    <>
      onThemeChange(val.target.value)}/>
      
    
  )
}

function ThemeResult(){
  const themeStatus = useContext(myContext)
  return(
    the theme is {themeStatus.theme}
  )
}

虽然这个例子直接写成非受控组件就完事,单纯是为了展示一下context的使用
React高级指引(上)_第3张图片

高阶组件

高阶组件是参数为组件,返回值为新组件的函数。
Tips:Refs 不会被传递

Refs转发

Ref 转发是一项将 ref 自动地通过组件传递到其一子组件的技巧

传递Refs到Dom组件
Tips:第二个参数 ref 只在使用 React.forwardRef 定义组件时存在。常规函数和 class 组件不接收 ref 参数,且 props 中也不存在 ref。

const FancyButton = React.forwardRef((props, ref) => (
  
));

function MyComp(){
  const ref = React.createRef();
  const handleButtonClick = useCallback(()=>{
    console.log('ref.current',ref.current);
  },[ref])
  return(
    Click me!
  )
}

Fragments

React 中的一个常见模式是一个组件返回多个元素。Fragments 允许你将子列表分组,而无需向 DOM 添加额外节点。可以使用一种新的,且更简短的语法来声明 Fragments:<>,但它并不支持 key 或属性。key是唯一可以传递给 Fragment 的属性

你可能感兴趣的:(react.js)