Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: How to integrate with Redux on v4? #2048

Closed
diegocouto opened this issue Jul 17, 2017 · 13 comments
Closed

Question: How to integrate with Redux on v4? #2048

diegocouto opened this issue Jul 17, 2017 · 13 comments

Comments

@diegocouto
Copy link
Contributor

That's a pretty silly question, but I'm having some trouble to connect with redux using react-native-router-flux v4. We have something like this:

const RouterWithRedux = connect()(Router);

class App extends Component {
  render () {
    return (
      <Provider store={store}>
        <RouterWithRedux>
          // Scenes...
        </RouterWithRedux>
      </Provider>
    );
  }
}

On v4, the actions aren't being dispatched to our reducers anymore. I noticed that, on the README, this is mentioned:

MobX-friendly: all scenes are wrapped with observer. You may subscribe to navigationStore (Actions in v3) and observe current navigation state. Not applicable to Redux.

Does it mean that it isn't possible to subscribe to events using Redux anymore?

@aksonov
Copy link
Owner

aksonov commented Jul 17, 2017 via email

@aksonov aksonov closed this as completed Jul 17, 2017
@diegocouto
Copy link
Contributor Author

Thanks again for your fast reply, aksonov! Well, this is a bit embarrassing but, to be honest, I'm still not sure about what is the proper way to do this. On v3, I had a route reducer which would only track the ActionConst.FOCUS.

This is my current reducer:

export const routes = createReducer({}, {
  [ActionConst.FOCUS] (state, action) {
    if (action.scene.hasOwnProperty('index') && action.scene.children) {
      return {
        ...state,
        scene: action.scene.children[action.scene.index]
      };
    }

    return {
      scene: action.scene
    };
  }
});

On the example project, this is how the reducer is created:

const reducerCreate = params => {
  const defaultReducer = new Reducer(params);
  return (state, action) => {
    return defaultReducer(state, action);
  };
};

I have unsuccessfully tried something like:

const reducerCreate = connect()(Router);

I may be confusing some vary basic concepts so, any idea would be helpful (even though I do understand that this would be more suitable on StackOverflow).

@diegocouto
Copy link
Contributor Author

For future reference, I built a custom router component, which is going to be used in place of my last RouterWithRedux.

import React, {Component} from 'react';
import {Router, Reducer} from 'react-native-router-flux';
import {connect} from 'react-redux';

class CustomRouter extends Component {
  reducerCreate (params) {
    const defaultReducer = new Reducer(params);
    return (state, action) => {
      this.props.dispatch(action);
      return defaultReducer(state, action);
    };
  }

  render () {
    return (
      <Router createReducer={this.reducerCreate.bind(this)} >
        {this.props.children}
      </Router>
    );
  }
}

export default connect()(CustomRouter);

On my root component, I just integrate it like this:

<Provider store={store}>
  <CustomRouter>
    // Scenes...
  </CustomRouter>
</Provider>

This approach is completely based on what's described here. I found it on this very interesting thread about the same subject.

Hope it helps. 😉

@marcellkiss
Copy link

Hi @diegocouto, could you make the replay work?

@diegocouto
Copy link
Contributor Author

Hi, @marcellkiss! To be honest, I didn't try to. We decided to update to v4 due to the smoother transitions but it represented a lot more work than we estimated, so we're dedicated to basic things first. hahaha

@augusto-altman
Copy link

@diegocouto Thanks man, it is working perfect 👍

@yordis
Copy link

yordis commented Oct 29, 2017

🔰

@aksonov would you put some example for Redux integration on the readme. I am new into RN/RNRF/Redux and this thread is the one that explained something that I could understand what I was doing wrong.

I read the readme but I wouldn't figure out what I was doing wrong because of my short experience on it.

@aksonov for people like me, could you add some working example with redux? 🙏 I think probably 90% of the people that works with React use Redux 😄

@yordis
Copy link

yordis commented Oct 29, 2017

@diegocouto 🔰🔰🔰 why do I have to dispatch the action without passing any state?

@yordis
Copy link

yordis commented Oct 29, 2017

btw, I just notice that a lot of tutorials on the internet are wrong, because the lookup in the action for the wrong key on the reducer.

This would be the final reducer

export default (state = DEFAULT_STATE, action) => {
  switch (action.type) {
    case ActionConst.FOCUS:
      return { ...state, scene: action.params } // <---- Notice that I am doing the lookup on params

    default:
      return state
  }
}

@diegocouto
Copy link
Contributor Author

Hi, @yordis! I'm glad to see that it's working for you.

I'm not sure if I could understand what you meant by dispatch the action without passing any state, but the idea here is that an action (and only an action, as you can see here) is dispatched and the store is going to use it to figure out what the next state is going to be.

As a reference, this is a reducer that I'm currently using on a project:

import {Actions, ActionConst} from 'react-native-router-flux';
import * as types from '../actions/types';
import createReducer from '../lib/createReducer';

export const routes = createReducer({currentScene: null, prevScene: null}, {
  [ActionConst.FOCUS] (state, action) {
    return {
      prevScene: state.currentScene,
      currentScene: action.routeName
    };
  },

  [types.BACK] (state, action) {
    return {
      prevScene: state.currentScene,
      currentScene: Actions.currentScene
    };
  }
});

As you can see, I only care about scenes names (I'm going to use it to identify whether I should close my app on Android or not).

@jaschaio
Copy link

jaschaio commented Nov 9, 2017

Hey @diegocouto, thanks for posting your solution here. This is nice, but redux replay still doesn't work. I can change the state but the state has no effect on my router. Even if I change the state my router stays the same. So this is not really working as one would expect it to work with Redux. Not sure if I am overseeing something, but I am not sure why this issue has been closed by @aksonov. I have yet to see a working solution with Redux.

Not sure if someone got a working example? CC @BerndWessels @marcellkiss @deoqc @augusto-altman

@aksonov
Copy link
Owner

aksonov commented Nov 9, 2017

It could be considered as duplicate of #2115
Probably docs should be improved for Redux integration - we are actively seeking for maintainers, PR is welcome...

@jaschaio
Copy link

jaschaio commented Nov 9, 2017

Thanks @aksonov for referencing #2115. The example given indeed works for me and I couldn't find it before. A one liner linking to the Redux example repo and related issue would probably already be enough for now.

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

No branches or pull requests

6 participants