React 对于初学者来说可能很棘手。但是,了解一些基本原理或技巧可以使成为一名高级 React 工程师更容易。
1. useEffect 清理回调在每次渲染时执行
大多数人认为它仅在组件卸载时执行,但事实并非如此。
在每次渲染时,
上一个渲染的清理回调都会在下一个效果执行之前执行
。
让我们看一个例子:
function SomeComponent() { const [count, setCount] = useState(0) useEffect(() => { console.log('The current count is ', count) return () => { console.log('The previous count is ', count) } }) return <button onClick={() => setCount(count + 1)}>Click me</button>}
这将记录以下内容:
// Component mountsThe current count is 0// ClickThe previous count is 0The current count is 1// ClickThe previous count is 1The current count is 2// Component unmountsThe previous count is 2
这对于创建 “unsubscribe then first subscribe” 模式很有用,这是 useEffect 唯一应该用于的事情。
当然,如果我们添加一个依赖数组,这些东西只有在依赖发生变化时才会被调用。
2. useEffect 是一个低级实用程序,应该只在类似库的代码中使用
初级 React 开发人员在不需要的时候使用 useEffect 是很常见的。这可能会使代码更加复杂、产生闪烁或细微的错误。
最常见的情况是同步不同的 useState,这时你实际上需要一个 useState:
function MyComponent() { const [text, setText] = useState("Lorem ipsum dolor sit amet") // You don't need to do this !!! const [trimmedText, setTrimmedText] = useState("Lorem ip...") useEffect(() => { setTrimmedText(text.slice(0, 8) + '...') }, [text])}function MyBetterComponent() { const [text, setText] = useState("Lorem ipsum dolor sit amet") // Do this instead: // (each time text changes, the component will re-render so trimmedText // will be up-to-date) const trimmedText = text.slice(0, 8) + '...'}
3. 使用 key 属性重置内部状态
当 prop 在元素上发生更改时,该元素的 render 不会被解释为更新,而是作为 unmount 加上具有 fresh state 的全新组件实例的 mount。
key
function Layout({ currentItem }) { /* When currentItem changes, we want any useState inside <EditForm/> to be reset to a new initial value corresponding to the new item */ return ( <EditForm item={currentItem} key={currentItem.id} /> )}
4. 不要将服务器状态放在 useState 中
服务器状态或多或少是数据库的快照,在加载页面时,该快照位于前端的内存中。
通常它由服务器状态管理器管理,如 react-query 或 Apollo。
如果你将它中的任何一个放在 useState 中,当查询刷新或发生变化时,你的 useState 的内容将不会更新。
5. ReactElement 与 ReactNode
ReactElement
只表示一个标记,而可以是 React 可以渲染的任何东西,也可以是 、 等。
ReactNode``ReactElement``string``number``boolean``array``null``undefined
// this is a ReactElementconst a = <div/>// these are ReactNodes1"hello"<div/>[2, <span/>]null
始终按原样键入 prop,你不想限制该组件可以放置的子组件。
children``ReactNode
JSX.Element
是一个内部的 Typescript 功能(不是由 React 库定义的),仅针对库开发人员。除此之外,它等效于 .
ReactElement