https://github.com/lucifier129/coeffect
An effect-management library for React
https://github.com/lucifier129/coeffect
effect-driven
Last synced: 9 months ago
JSON representation
An effect-management library for React
- Host: GitHub
- URL: https://github.com/lucifier129/coeffect
- Owner: Lucifier129
- Created: 2020-12-19T12:47:25.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2020-12-19T13:52:44.000Z (over 5 years ago)
- Last Synced: 2025-04-20T20:18:08.387Z (about 1 year ago)
- Topics: effect-driven
- Language: TypeScript
- Homepage:
- Size: 5.86 KB
- Stars: 14
- Watchers: 2
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Coeffect
An effect-management library for React
`Coeffect` 让我们在 React 组件外部管理 `Effect`,尽情使用 `side-effect` 和 `mutable-state`,不受 `React` 组件的 `immutable` 和 `pure` 的限制。
`Coeffect` 里的副作用遵循 `useEffect(effectFunction)` 的规则,是渲染安全的,但能够很好地和 `React` 组件协同工作。
## Usage
```typescript
import { createEffect } from 'coeffect'
/**
* 定义你的 Effect 类型
* options 描述数据参数
* consumer 描述回调方法
* handler 描述控制方法
*/
export type TimeoutEffect = {
options: {
duration: number
}
consumer: {
onStart?: () => any
onStop?: () => any
onEnd?: () => any
onUpdate?: (currDuration: number, prevDuration: number) => any
}
handler: {
start: (duration?: number) => void
stop: () => void
update: (duration: number) => void
isStart: () => boolean
}
}
/**
* 根据 Effect 类型,创建 Effect 对象
*/
export const Timeout = createEffect((consumer, options) => {
let tid: number | null = null
let duration = options.duration // 消费 options 参数
// 实现 handler 方法
return {
start() {
if (tid !== null) return
tid = setTimeout(() => {
tid = null
consumer.onEnd?.() // 调用 consumer 方法
}, duration)
consumer.onStart?.()
},
stop() {
if (tid === null) return
clearTimeout(tid)
tid = null
consumer.onStop?.()
},
update(newDuration) {
duration = newDuration
this.stop()
},
isStart() {
return tid !== null
}
}
})
// 在 React 组件中使用
const CopyButton: FC = ({ text, children }) => {
const [noticing, setNoticing] = useState(false)
/**
* 使用时,传递 consumer 回调方法,传递 options 参数
*/
const notifier = Timeout.useEffects(
{
onStart: () => {
// 在 consumer 方法中,将数据同步到 state
setNoticing(true)
},
onEnd: () => {
setNoticing(false)
},
onStop: () => {
setNoticing(false)
}
},
{
duration: 1500
}
)
const handleCopy = (text: string) => {
// 可以按需调用,而非被动 re-render
if (!text.includes('*')) {
notifier.start() // 调用 handler 控制方法
}
}
return (
{children}
)
}
```