无障碍辅助功能
无障碍辅助功能是使得辅助技术正确解读网页的必要条件
可以从以下几个方面考虑设计:语义化的HTML、无障碍的表单、控制焦点、鼠标和指针事件、语言、文档标题、色彩对比度等
代码分割
对应用进行代码分割能够“懒加载”当前用户所需要的内容,能够显著地提高应用性能。尽管并没有减少应用整体的代码体积,但避免加载用户永远不需要的代码,在初始加载的时候减少所需加载的代码量。
- import()
- 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组件才能成为错误边界组件
错误边界无法捕获以下场景中产生的错误:
- 事件处理,若想在事件处理器内部捕获错误,可使用普通的 JavaScript try / catch 语句
- 异步代码(例如 setTimeout 或 requestAnimationFrame 回调函数)
- 服务端渲染
- 它自身抛出来的错误(并非它的子组件)
- 如果一个错误边界无法渲染错误信息,则错误会冒泡至最近的上层错误边界,这也类似于 JavaScript 中 catch {} 的工作机制。
show you the code
// 未添加错误边界
function App(){
return (
正常展示的内容
);
}
function MyComp(){
return(
{ Math.random() > 0.2 ? new Error('自定义错误!!!') : '没有错误'}
)
}
// 添加错误边界后的代码
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
}
}
}
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的使用
高阶组件
高阶组件是参数为组件,返回值为新组件的函数。
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 的属性