Skip to content
This repository has been archived by the owner on Feb 19, 2022. It is now read-only.

Accessing component props in effects #43

Open
artemkochnev opened this issue May 8, 2017 · 6 comments
Open

Accessing component props in effects #43

artemkochnev opened this issue May 8, 2017 · 6 comments

Comments

@artemkochnev
Copy link

I'm trying out freactal for an internal admin tool, and I'm running into an issue with handling history changes as a response to effects.

I'm using react-router@v4 for routing, which no longer exposes a history singleton, meaning that I have to wrap my components in withRouter to get access to the history object on my component's props and be able to make changes to it. However, I'd like to redirect the user after making an API call, but there isn't a way to get at the props in an effect, so I end up writing component methods like these:

addAsset = async params => {
  const { effects: { addAsset }, history } = this.props;
  await addAsset(params);
  history.push('/marketing/assets');
};

I've thought about wrapping my root component in withRouter and then setting the history in my state, but then I still can't access the state within an effect to be able to make changes to it.

Do you have any thoughts on how to best get around this issue without having to write a bunch of boilerplate component methods?

@artemkochnev artemkochnev changed the title Accessing component props in effects Accessing component props in effects? May 8, 2017
@acjay
Copy link

acjay commented May 8, 2017

This struck me as perhaps a limitation of Freactal's current API. Generally speaking, the need to couple to external systems, whether that's a router, a web socket, etc.

I almost wish there were a separate key under provideState as a holding place for other references that should be available to initialize and effects throughout the stack.

@markacola
Copy link
Contributor

markacola commented May 16, 2017

Just a note that you can access component props and context from initialState.
One way around this issue is storing reference to the required props in state:

const withState = provideState({
  initialState: (props, context) => ({
    router: props.router
  }),
  effects: {
    doSomethingThenPush: (effects) => state => {
      doSomething().then(() => {
        state.router.push('/somewhere')
      })
      return state
    }
  }
})

export default withRouter(withState(SomeComponent))

Feels like a bit of an anti-pattern, and would love feedback on this, but this is a work around that I am using. Somehow having access to component props in effect directly would be great.

@acjay
Copy link

acjay commented May 16, 2017

While that seems like a totally pragmatic solution, it just feels like both props and state are meant to be fairly primitive data, not directly exposing complex APIs. It seems like the latter should be encapsulated within effects. You do this, to be fair, but it would be great to have a way to route these references to effects in a way that leaves props and state out of the equation..

@divmain
Copy link
Contributor

divmain commented May 27, 2017

Please see the discussion in #36. I'm looking at a more powerful middleware approach that would allow you access to the state provider instance.

@divmain divmain changed the title Accessing component props in effects? Accessing component props in effects May 27, 2017
@ericclemmons
Copy link

Came here surprised as well that effects don't have access to props.

In particular, I have an effect that would call a slightly different GraphQL query based on props like "limit" or "offset".

As it is now, I'm trying to create a HoC that generates effects at runtime with each render to access these, but it strikes me as expensive.

@bingomanatee
Copy link

I'm against it. The whole moswen flow is you feed set up the state, and it feeds information into the view; you interact, and you feed deltas into the state. Giving state a special window into props feels like a "backwash" -- because props is very transient to WHERE in the dom tree you are. If you want to pull props, do it in the simple function or components - the sate machine should operate without being welded to any particular part of the view.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants