salsita / prism

React / Redux action composition made simple http://salsita.github.io/prism/
496 stars 24 forks source link

Mount order and saga registering #67

Closed biirus closed 7 years ago

biirus commented 7 years ago

Hi, folks! I'm stuck on registering saga problem.

There are a few components:

// Player

class Player extends React.Component {
  componentDIdMount () {
    console.log('Player Mount');
  }

  render () {
    return (
      <div>...</div>
    );
  }
}

export default view(Player)
// Lesson

class Lesson extends React.Component {
  componentDidMount () {
    this.props.dispatch({type: 'FETCH'});
    console.log('Lesson Mount');
  }

  render () {
    return (
        <div>
          <Player />
        </div>
    );
  }
}

export default view(Lesson);

And Lesson has an updater with saga.

// Lesson Updater

function* saga () {
  while (true) {
    const action = yield take('FETCH');
    yield call(someGeneratorFunction(action));
  }
}

export default new Updater(true, saga)
  .toReducer();

Console logs appear in such order Player Mount => Lesson Mount.

The HOC view mounts after it's inner component, that's why Lesson.@@redux-elm/Mount action fires after Lesson component mounts. When Lesson dispatches {type: 'FETCH'} it's saga has not been mounted yet.

Why I have such order Inner Mount => Outer Mount and how I can fix the saga mounting.

P.S. sorry for my bad English =(

namjul commented 7 years ago

The Lesson saga will be called when Lesson view gets mounted. So if you want to call a function when Lesson gets mounted just call it in the saga. The saga should be used for initialization.

biirus commented 7 years ago

@namjul, thanks for your advice. It seems to be right choice.

dvshur commented 7 years ago

@namjul, but what if you want this function to access some props available only in the component view?

Like, for example, if you pass an API URL to fetch from in component props. How do you make an on-mount API request to this URL?

<Player fetchUrl='https://some/api/url' />
namjul commented 7 years ago

@dvshur i think there is no simple solution for this but i guess you could extend the redux-elm/view and override the dispatch function to take in the props.

dvshur commented 7 years ago

Maybe we should make a feature request? To provide a simple way to access component props in saga?

As far as I understand you can currently use select to get component state in saga, but there is no way to access the props. And sometimes you need to.

namjul commented 7 years ago

To note is that with this approach you would only be able to access the initial props. But yes maybe that change does make sense and can be part of redux-elm.

biirus commented 7 years ago

I'm still stuck with it.

If I move this.dispatch({ type: Mount }); from componentDidMount method to componentWillMount in redux-elm/view.js the code works well.

@tomkis1, can you explain me, what am I doing wrong? Or may be I should make a PR.

tomkis commented 7 years ago

redux-elm aka prism does not deal with "Components" anymore, you don't need to hassle with Component lifecycle, should be solved in user land.