Replies: 2 comments
-
It's possible to use Mobx for local state. You can even do it with class stores: class SomeStore {
constructor() {
makeAutoObservable(this);
}
...
}
const Component = observer(() => {
const [store] = useState(() => new SomeStore());
...
}) I often use this approach when the logic inside component gets complicated. But it's not recommended to mix React props with observable data:
Regarding your example I'd suggest lifting state up: https://reactjs.org/docs/lifting-state-up.html export const Image = forwardRef<HTMLImageElement, ImageProps>((props, ref) => {
- const [src, setSrc] = useState(props.src)
-
- useEffect(() => {
- setSrc(props.src!)
- }, [props.src])
function onError(ev: React.SyntheticEvent<HTMLImageElement>) {
- props.fallback && setSrc(props.fallback)
+ props.fallback && props.onChange(props.fallback)
props.onError?.(ev)
}
// noinspection HtmlRequiredAltAttribute
- return <img {...props} ref={ref} src={src} onError={onError} />
+ return <img {...props} ref={ref} src={props.src} onError={onError} />
}) So if you make your parent component state the single source of truth, you won't need to sync this state with another state. |
Beta Was this translation helpful? Give feedback.
-
Now, I think of another way to implement vue hooks using mobx. I want to know whether this way of use will have performance issues in larger projects import { action, computed, observable } from 'mobx'
import { observer } from 'mobx-react'
import React, { useCallback, useMemo, useState } from 'react'
function useVueReactive<T extends object>(value: T): T {
const [state] = useState(() => observable(value))
return state
}
function useVueRef<T>(value: T): { value: T } {
return useVueReactive({ value })
}
function useVueComputed<T>(fn: () => T): { value: T } {
const computedValue = useMemo(() => computed(fn), [])
return {
get value() {
return computedValue.get()
},
}
}
function useVueFn<T extends (...args: any[]) => any>(fn: T): T {
return useCallback(action(fn), [])
}
const defineComponent = observer
const UseRefDemo = defineComponent(() => {
const state = useVueRef(0)
const computedValue = useVueComputed(() => state.value * 2)
const onInc = useVueFn(() => {
state.value++
})
return (
<div>
<button onClick={onInc}>增加</button>
<div>{computedValue.value}</div>
</div>
)
})
const UseReactiveDemo = defineComponent(() => {
const user = useVueReactive({ name: 'liuli', age: 0 })
const hello = useVueComputed(() => `hello ${user.name}`)
const onIncAge = useVueFn(() => {
user.age++
})
const onChangeName = useVueFn(() => {
user.name = 'test'
})
return (
<div>
<button onClick={onChangeName}>改变名字</button>
<button onClick={onIncAge}>增加年龄</button>
<div>{hello.value}</div>
<div>{user.age}</div>
</div>
)
})
export const App: React.FC = defineComponent(() => {
return (
<div>
<UseReactiveDemo />
<UseRefDemo />
</div>
)
})
|
Beta Was this translation helpful? Give feedback.
-
Just an idea, I want to ask the annoying dependency management of react hooks. Has anyone tried to use mobx to complete state management before? Even if it is a partial state, it still creates a store with a closure and wraps the component with observer to make it responsive.
Or, is there any way to modify the state without using
setState
and carefully maintain theeffect
, similar to theref/reactive
in vue3. Is there a way to do that with the help of mobx?Below is a simple example, maybe there is a better way?
Beta Was this translation helpful? Give feedback.
All reactions