函数式组件
使用React.FC<Props>
声明泛型,方便我们推导类型
如果在使用组件时在标签内部添加了子元素,可以通过props.children
访问到,类似于vue的插槽?在react18之后改为需要手动定义类型
tsx
interface Props {
children: React.ReactNode //手动声明children
}
props遵守单向数据流,子组件无法直接修改父组件传过来的值(在React源码中会使用Object.freeze
冻结props)。不过可以让父组件传入回调函数,来达到类似emit的效果
其他通信可以直接用浏览器的事件进行发布订阅
tsx
function a () {
e = new Event("e");
window.dispatchEvent(e);
}
function b(){
window.addEventListener('e',callback);
}
受控组件
受控组件一般是指表单元素,表单的数据由React的 State 管理,更新数据时,需要手动调用setState()
方法,更新数据。因为React没有类似于Vue的v-model,所以需要自己实现绑定事件。File类型的表单则无法成为受控组件,因为它的值不能让浏览器程序直接设置。
非受控组件指的是该表单元素不受React的State管理,表单的数据由DOM管理。通过useRef()来获取表单元素的值。
传送组件(API)
将一个组件渲染到DOM的任意位置,跟Vue的Teleport组件类似。
入参:
- children:要渲染的组件
- domNode:要渲染到的DOM位置
- key?:可选,用于唯一标识要渲染的组件
返回一个React元素(即jsx),这个元素可以被React渲染到DOM的任意位置
应用:
- 弹窗
- 下拉框
- 全局提示
- 全局遮罩
- 全局Loading
tsx
import { createPortal } from 'react-dom';
export const Modal = () => {
return createPortal(<div className="modal">
<div className="modal-header">
<div className="modal-title">标题</div>
</div>
<div className="modal-content">
<h1>Modal</h1>
</div>
<div className="modal-footer">
<button className="modal-close-button">关闭</button>
<button className="modal-confirm-button">确定</button>
</div>
</div>,
document.body
)
}
异步组件
Suspense 是一种异步渲染机制,其核心理念是在组件加载或数据获取过程中,先展示一个占位符(loading state),从而实现更自然流畅的用户界面更新体验。
应用:
- 异步组件懒加载
- 请求过程占位
- 图片占位
入参:
- fallback: 指定在组件加载或数据获取过程中展示的组件或元素
- children: 指定要异步加载的组件或数据,其实就是可以放在标签内部用的。
tsx
// components/Async/index.tsx
export const AsyncComponent = () => {
return <div>Async</div>
}
export default AsyncComponent
// App.tsx
import React, { useRef, useState, Suspense,lazy } from 'react';
const AsyncComponent = lazy(() => import('./components/Async'))
const App: React.FC = () => {
return (
<>
<Suspense fallback={<div>loading</div>}>
<AsyncComponent />
</Suspense>
</>
);
}
export default App;
其他
Fragment
使用<Fragment>
时 通常使用 <>...</>
代替,它们都允许你在不添加额外节点的情况下将子元素组合。
StrictMode
使用<StrictMode>
帮助你在开发过程中尽早地发现组件中的常见错误。
React-dom
首先,react支持所有浏览器内置的HTML,SVG组件