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

Implementation with redux #51

Open
Jacky9425 opened this issue Dec 19, 2019 · 8 comments
Open

Implementation with redux #51

Jacky9425 opened this issue Dec 19, 2019 · 8 comments

Comments

@Jacky9425
Copy link

If you're using redux for your state management, a good idea might be to start the Proximity Observer where you create your redux store, and have the proximity events dispatch appropriate actions. The rest of your app can then subscribe to state/store changes as needed, and benefit from the proximity events this way. What a beautiful separation of concerns!

Hi, can you explain futher the statement above? Regarding Proximity Observer can be initialised during redux store creation, does the start() initialises at store.js or index.js where the redux store is integrated on the app?

@nandorojo
Copy link

I'm not sure exactly what they meant, but my guess would be that you initialize your proximity observer in the direct child of your redux Provider component. That way, any events that get fired can immediately dispatch actions from there, and you only have one listener set up.

My best guess

App.js

// ...
import * as RNEP from '@estimote/react-native-proximity'

export default () => {
  return (
    <Provider store={store}>
      <Observer />
    </Provider>
  )
}

const Observer = () => {
  const dispatch = useDispatch()
  useEffect(() => {
   // set up listener here
    const zone = new RNEP.ProximityZone(5, 'kitchen')
    zone.onEnterAction = (context) => {
     dispatch({ enteredKitchen: true })
    }
    zone.onExitAction = (context) => {
     dispatch({ enteredKitchen: false })
    }
  }, [dispatch])

  return <App />
}

What I would do

If you're like me, you like putting this kind of logic into custom react hooks, so that you can easily refactor code.

App.js

import * as React from 'react'
import { useObserver } from './use-observer.js'
import { Provider } from 'react-redux'
import { store } from '../path/to/your/store'

export default () => {
  return (
    <Provider store={store}>
      <Observer />
    </Provider>
  )
}

const Observer = () => {
  useObserver()
  return <App />
}

use-observer.js

import * as RNEP from '@estimote/react-native-proximity'
import { useDispatch } from 'react-redux'

export const useObserver = () => {
  const dispatch = useDispatch()
  useEffect(() => {
    // set up listener here
    const zone = new RNEP.ProximityZone(5, 'kitchen')
    zone.onEnterAction = context => {
      dispatch({ enteredKitchen: true })
    }
    zone.onExitAction = context => {
      dispatch({ enteredKitchen: false })
    }
  }, [dispatch])
}

@jacky-ew
Copy link

Thanks for the suggestion @nandorojo. However i am not planning to implement react hooks onto the project. However i've tried before dispatching action to modify states in redux store in background. It seems like i cannot access the state or props (normally we access the states thru mapStateToProps/mapDispatchToProps) to execute the functions that requires redux state. Therefore i might try to put the listener at the bottom level of the stack navigator (HomePage) to experiment first

@nandorojo
Copy link

You could also access the store object directly, without doing it through props, if you’re using background mode for beacons.

@jacky-ew
Copy link

any documentation as reference? @nandorojo

@nandorojo
Copy link

https://daveceddia.com/access-redux-store-outside-react/

store.js

import { createStore } from 'redux';
import reducer from './reducer';

export const store = createStore(rootReducer)

observer.js

import { store } from '../path/to/store'

...
zone.onEnterAction = context => {
  store.dispatch({ enteredKitchen: true })
}

You'll probably want to implement redux-persist if you want it to work while cached/in the background too. I'm not sure if this works, though, so maybe look into redux persist with background tasks.

@jacky-ew
Copy link

Hi, thanks for the reference.
Im already using redux-persist, and the last experiment is that i cannot access the persisted state. store.getState() only returns the default state.

But for that case it was a headless task. I will try experiment more on that, thanks

@nandorojo
Copy link

This might help: rt2zz/redux-persist#1066

It appears that you can dispatch actions, not sure about accessing state.

@jacky-ew
Copy link

Thanks for the suggestion.

i manage to access the states and actions when initialising the redux store with the app at App.js.
So i suppose if i move the redux store initialisation to index.js, i should able to access the subscribed state and actions

index.js

const reduxApp = () => (
     <Provider store={store}>
         <App />
     </Provider>
)

console.log(store.getState()); <== should return me the tracked state instead of the default state/previous state

AppRegistry.registerComponent("sampleApp", () => reduxApp);

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

No branches or pull requests

3 participants