formik表单处理框架
引入代码分割最佳方式是通过动态import()
之前模式:
import { add } from './math'
console.log(add(16, 26))
使用之后:
import('./math')
.then(math => {
console.log(math.add(16, 26))
})
webpack解析该语法时会自动进行代码分割。Create React App已配置该功能,Next.js已支持切无需配置。
React.lazy
支持想渲染常规组件一样处理动态引入(的组件)
import OtherComponent from './OtherComponent'
使用之后:
const OtherComponent = React.lazy(() => import('./OtherComponent'))
代码会在组件首次渲染时,自动导入包含OtherComponent
组件的包。
React.lazy
接受一个函数,这个函数需要动态调用import()
。它必须返回一个Promise
,该Promise需要resolve一个default export的React组件。
然后在Suspense
组件中渲染lazy组件,如此使得我们可以使用在等待加载lazy组件时做优雅降级(如loading提示器等)
import React, { Suspense } from 'react'
const OtherComponent = React.lazy(() => import('./OtherComponent'))
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
)
}
fallback
属性接受任何在组建过程中你想展示的React元素。你可以将Suspense
组件置于懒加载组件之上的任何位置。
默认情况下组件切换会显示兜底组件,使用startTransition
API可以在切换之前显示旧组建而不是兜底UI。
import React, { Suspense } from 'react'
import Tabs from './Tabs'
import glimmer from './Glimmer'
const Comments = React.lazy(() => import('./Comments'))
const Photos = React.lazy(() => import('./Photos'))
fucntion MyComponent() {
const [tabs, setTab] = React.useState('photos')
function handleTabsSelect(tab) {
startTransition(() => {
setTab(tab)
})
}
return (
<div>
<Tabs onTabSelect={handleTabSelect}/>
<Suspense fallback={<Glimmer />}>
{tab === 'photos' ? <Photos /> : <Comments />}
</Suspense>
</div>
)
}
useCallback is a React Hook that lets you cache a function definition between re-renders.
const cachedFn = useCallback(fn, dependencies)
export default function ProductPage({ productId, referrer, theme }) {
const handleSubmit = useCallback((orderDetails) => {
post('/product/' + productId + '/buy', {
referrer,
orderDetails,
})
}, [productId, referrer])
}
useContext is a React Hook that lets you read and subscribe to context from your component.
call useContext at the top level of your component to read and subscribe to context.
the context value is determined as the value passed to the closet SomeContext.Provider above the calling component in the tree. if there is no such provider, then the returned value will be the defaultValue
you have passed to createContext for that context. The returned value is always up-to-date. React automatically re-renders components that read some context if it changed
import { useContext } from 'react'
function MyComponent() {
const theme = useContext(ThemeContext)
}
function MyPage() {
return (
<ThemeContext.Provider value="dark">
<MyComponent/>
</ThemeContext.Provider/>
)
}
function MyProviders({ children, theme, setTheme }) {
const [currentUser, setCurrentUser] = useState(null)
return (
<ThemeContext.Provider value={theme}>
<CurrentUserContext.Provide
value=
>
{children}
</CurrentUserContext.Provider>
</ThemeContext.Provider>
)
}
useMeo is a React Hook that lets you cache the result of a calculation between re-renders.
const cachedValue = useMemo(calculateValue, dependencies)
const visibleTodos = useMemo(
() => filterTodos(todos, tab),
[todos, tab]
)
const [state, setState] = useState(initialState)
React will store the next state, render your component again with the new values, and update the UI.
custom hooks let you share stateful logic but not state itself. Each call to a Hook is completely independent from every other call to the same Hook.
The code inside your comtom Hooks will re-run during every re-render of your component. This is why, like components, costom Hooks need to be pure. Think of Custom Hooks’ code as part of your component’s body.
Because custom Hooks re-render together with your component, they always receive the latest props and state.
most of your app’s Effects will be in custom Hooks.
Keep your custom Hooks focused on concrete high-level use cases.
benefit of wrapping Effects in custom hook:
Recap
use
followed by a capital letter.useMount
. Keep their purpose specific.function useFormInput(initialValue) {
const [value, setValue] = useState(value)
function handleChange(e) {
setValue(e.target.value)
}
const inputProps = {
value: value,
onChange: handleChange,
}
return inputProps
}
const firstNameProps = useFormInput('mary')
<input {...firstNameProps} />