cerebral / overmind

Overmind - Frictionless state management
https://overmindjs.org
MIT License
1.58k stars 95 forks source link

Is there any way to change states outside component? #530

Closed p32929 closed 2 years ago

p32929 commented 3 years ago

Hello, thank you for the amazing library. I just have one question: Is there any way to change state(s) from outside of a component?

I mean, now we do this to change states inside a component:

const Test: React.FC<Props> = (props) => {
    const {counter} = useActions()
    const {addCounter} = useAppState()

    return <Button onClick={()=> {
        addCounter(1)
    }}>{counter}</Button>

}

export default Test;

And to change outside of a component, I do this:

// In a different file
export class SomeClass {
    static changeCounter(addCounter) {
        addCounter(1)
    }
}

// in Test.tsx
const Test: React.FC<Props> = (props) => {
    const {counter} = useActions()
    const {addCounter} = useAppState()

    return <Button onClick={()=> {
        SomeClass.changeCounter(addCounter)
    }}>{counter}</Button>

}

export default Test;

I pass the actions down to the functions and then change states. Its okay, until there's just one action to pass. But if there's multiple actions to pass down through functions, the code looks really messy.

Is there any way, we can change states without needing to pass it down through a component through a function parameter?

Thanks @christianalfoni

grandevel commented 3 years ago

You might want to consider flipping it around - instead of the presentation layer (React) creating a wireup between your file and overmind actions, why not have the action reference the file and do it within the action?

So addCounter() calls SomeClass.changeCounter - instead of the other way around. Or, if you really need changeCounter to be called like this, why not set it up as an action so it can handle itself?

It's easy to forget that actions can sit across multiple files and be spread into the same namespace... i.e.

import { myActions } from 'file1' import * as otherActions from 'file2'

const overmind = createOvermind({state, actions: {...myactions, ...otherActions}); etc.

Far from clean, but still better than handing the view layer cross-wire stuff...

p32929 commented 3 years ago

Pardon my ignorance, but would you mind writing a short example? or link any project source code? Thanks a million @grandevel

christianalfoni commented 3 years ago

Hi there 😄

I am a little bit unsure on how you want to organize this. The pattern of using a class with static methods where you pass in a function to call it... not sure why you do that? 🤔

It seems like you have a concept of: App Logic (Overmind) <> Components <> App Logic (Custom classes)

While you should be able to clean this up just having: App Logic (Overmind) <> Components?

So not calling actions via this additional layer of custom classes?

p32929 commented 3 years ago

So, to explain, what I'm looking for, I created this repo: https://github.com/p32929/react-typescript-overmind-counter-example

I want to change states here: https://github.com/p32929/react-typescript-overmind-counter-example/blob/139ca67d8137f3de254c7c21b58c0c2183d81166/src/Others/Foo.ts#L3

Without needing to pass down the actions from the components. and want to change states on the button clicks: https://github.com/p32929/react-typescript-overmind-counter-example/blob/139ca67d8137f3de254c7c21b58c0c2183d81166/src/Components/Counter.tsx#L31

Is there any way to do it? Thanks

@christianalfoni @grandevel

p32929 commented 3 years ago

Hello @christianalfoni , @grandevel Sorry to bother you again, but it would be really helpful either if you can answer or if you can at least say, if its possible or not. Thanks a million

p32929 commented 3 years ago

Hello? @christianalfoni @grandevel

p32929 commented 3 years ago

Its been more than a month but no answers :(

henri-hulski commented 3 years ago

@p32929 Hi! Maybe you should asked this question on the discord channel. I think it belongs there as it's a support question, not an issue. And there're much more folks out there which can help you. Christian also frequently answers questions over there.

p32929 commented 3 years ago

Thank you so much. I didn't know there's a discord channel.

grandevel commented 2 years ago

Closing this as it looks resolved, but please pick back up in the discord channel if more assistance needed.