| name | react |
| description | Guides React component implementation, performance optimization, and state management thresholds. Triggered when handling components, pages, or UI logic. |
React Development Guide
This skill provides a comprehensive guide for building React components in the project, focusing on performance, state management thresholds, and modular organization.
1. Component Architecture
1.1 Standard Component Pattern
Every component should follow the standard export pattern to ensure responsiveness (MobX) and performance (Memoization).
import { observer } from 'mobx-react-lite'
const Index = (props: IProps) => {
const { data } = props
return (
<div className='flex flex-col p-4'>
{/* Content */}
</div>
)
}
export default new $app.handle(Index).by(observer).by($app.memo).get()
export default $app.memo(Index)
1.2 Module Splitting (Fractal Architecture)
Large modules must be split according to fractal patterns to maintain high maintainability and clear scope.
1.3 Props Management Pattern
To maintain component cleanliness and reference stability, follow these patterns for declaring and passing Props:
- Performance-sensitive Props: For props that trigger heavy operations (e.g., Ant Design theme configuration, large data trees), use
useMemo.
- Standard Props: If they don't trigger expensive re-renders, simple objects can be declared directly.
- Naming: Always use
props_* prefix as the naming convention for internal props objects.
2. Performance Optimization
2.1 Function Reference Management
To prevent unnecessary re-renders of child components, all functions (event handlers, callbacks) must have stable references.
import { useMemoizedFn } from 'ahooks'
const handleClick = useMemoizedFn(() => {
})
<Child onClick={handleClick} />
2.2 Props Comparison Optimization
$app.memo performs deep comparison. To cooperate with its work and avoid unnecessary checks on heavy objects:
- Reference Type Values: For non-primitive data type props (objects, arrays), use global
$copy(value) to pass value-based copies.
- Principle: Using
$copy ensures that even if the parent component re-renders and creates new object references, as long as the data content hasn't changed, the child component won't re-render.
<LargeComponent
config={$copy(config_object)}
items={$copy(data_array)}
/>
2.3 Conditional Style Classes
Use the global $cx (classix) utility for efficient, readable conditional CSS class merging.
<div
className={$cx(
'base-class',
isActive && 'active-class',
isError ? 'text-red' : 'text-gray'
)}
/>
3. State Management Thresholds
3.1 State Hierarchy
- Shared State: Managed by top-level models (e.g.,
GlobalModel), injected via tsyringe, obtained using useGlobal.
- Simple Component State: If reactive variables/logic blocks are less than or equal to 4, manage with standard Hooks (
useState, useMemo).
- Complex Component State: If a component's internal logic exceeds 4 reactive variables, you must create a standalone MobX model (Local Model) coexisting with that component.
3.2 Local Model Implementation
Local models also use tsyringe dependency injection.
import { makeAutoObservable } from 'mobx'
import { injectable } from 'tsyringe'
@injectable()
export class LocalModel {
v1 = ''
v2 = 0
v3 = []
v4 = false
v5 = {}
constructor() {
makeAutoObservable(this, {}, { autoBind: true })
}
action() { }
}
const Index = () => {
const [local] = useState(() => container.resolve(LocalModel))
return <div onClick={local.action}>{local.v1}</div>
}
4. Summary Checklist