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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
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