V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
SHF
V2EX  ›  分享创造

react-object-model: 面向对象的 react 状态管理,只依赖 react hooks,简单、易用、高效

  •  1
     
  •   SHF ·
    ShenHongFei · 2021-04-17 13:04:20 +08:00 · 1430 次点击
    这是一个创建于 1321 天前的主题,其中的信息可能已经有所发展或是发生改变。

    react-object-model

    面向对象的 react 状态管理,只依赖 react hooks,简单、易用、高效

    Github

    https://github.com/ShenHongFei/react-object-model

    Usage

    import React from 'react'
    import ReactDOM from 'react-dom'
    
    import Model from 'react-object-model'
    
    function Example () {
        const { value } = counter.use(['value'])
        
        return <div>
            <div>counter.value = {value}</div>
            <div>
                <button onClick={ () => { counter.increase() } }>+1</button>
                
                <button onClick={ async () => {
                    await counter.increase_async()
                    console.log('counter.value', counter.value)
                } }>+1 (delay 2s)</button>
                
                <button onClick={ () => { counter.reset() } }>reset</button>
            </div>
        </div>
    }
    
    
    class Counter extends Model <Counter> {
        value = 0
        
        reset () {
            this.set({ value: 0 })
        }
        
        increase () {
            this.set({ value: this.value + 1 })
        }
        
        async increase_async () {
            await new Promise(resolve => { setTimeout(resolve, 2000) })
            this.set({ value: this.value + 1 })
        }
    }
    
    let counter = new Counter()
    
    ReactDOM.render(<Example/>, document.querySelector('.root'))
    

    Edit vigilant-northcutt-8p0q4

    Implementation

    import { useEffect, useRef, useState } from 'react'
    
    export class Model <T> {
        protected _selectors: Map<React.MutableRefObject<(keyof T)[]>, ({ }) => void>
        
        protected _state: any
        
        constructor () {
            Object.defineProperty(this, '_selectors', {
                configurable: true,
                enumerable: false,
                writable: true,
                value: new Map<React.MutableRefObject<(keyof T)[]>, ({ }) => void>()
            })
            
            Object.defineProperty(this, '_state', {
                configurable: true,
                enumerable: false,
                writable: true,
                value: { }
            })
        }
        
        use (selector?: (keyof T)[]) {
            const ref = useRef(selector)
            this._selectors.set(ref, useState({ })[1])
            useEffect(() => {
                return () => { this._selectors.delete(ref) }
            }, [])
            return this as any as T
        }
        
        set (data: Partial<T>) {
            Object.assign(this, data)
            this.render()
        }
        
        render () {
            this._selectors.forEach( (setState, { current: selector }) => {
                if (selector && !selector.find( (key: keyof T) => this[key as any] !== this._state[key] ))
                    return
                setState({ })
            })
            this._state = { ...this }
        }
    }
    
    export default Model
    
    2 条回复    2021-04-21 21:13:15 +08:00
    netnr
        1
    netnr  
       2021-04-21 18:58:37 +08:00 via Android
    怎么回事,撞头像了
    SHF
        2
    SHF  
    OP
       2021-04-21 21:13:15 +08:00
    @netnr 巧了~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3193 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 14:04 · PVG 22:04 · LAX 06:04 · JFK 09:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.