tshaddix / webext-redux

A set of utilities for building Redux applications in Web Extensions.
MIT License
1.22k stars 180 forks source link

Help: props not showing or updating in popup menu #217

Closed WolffDev closed 5 years ago

WolffDev commented 5 years ago

Hey, I am kinda new to react and redux. For some reason, my state props are not showing up in my popup component. It seems like the store is not connected properly, somehow. When I fire the action, the state gets updated, but the UI is not updating - somehow it's not synced with the state. What am I missing?

The popup.js is the browser_action that gets rendered when the user clicks the extension icon.

Here are my files:

// auth-reducer.js
import { LOGIN, LOGOUT } from '../../../../shared/store-consts'

const authState = {
  isAuthenticated: false,
  uid: ''
}

export default (state = authState, action) => {
  switch (action.type) {
    case LOGIN:
      return {
        ...state,
        uid: action.payload.uid,
        isAuthenticated: true
      }

    case LOGOUT:
      return {}

    default:
      return state
  }
}
// reducers.js
import {combineReducers} from 'redux'

import auth from './auth-reducer'

const reducers = combineReducers({
    auth
})

export default reducers
// store.js
import { createStore, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'

import reducers from './reducers'

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

const store = createStore(reducers, composeEnhancers(applyMiddleware(thunk)))

export default store
// background.js
import { wrapStore } from 'webext-redux'

import reduxStore from './store'

wrapStore(reduxStore, {portName: 'APP'})
// auth-actions.js
import { LOGIN } from '../../../../shared/store-consts'

export const login = uid => ({
  type: LOGIN,
  payload: {uid}
})
// App.js
import React from 'react'
import { connect } from 'react-redux'

import { login } from '../background/store/actions/auth-actions'

const App = ({ isAuthenticated, login, uid }) => (
  <>
    <p>Testing Auth from store</p>
    <p>Loggedin: {isAuthenticated ? 'true' : 'false'}</p>
    <p>UID: {uid}</p>
    <button type="button" onClick={() => login('123')}>
      Login 123
    </button>
  </>
)

const mapStateToProps = state => {
  return {
    isAuthenticated: state.isAuthenticated,
    uid: state.uid
  }
}

const mapDispatchToProps = dispatch => ({
  login: uid => dispatch(login(uid))
})

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(App)
// popup.js
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { Store } from 'webext-redux'

import App from './App'

const proxyStore = new Store({portName: 'APP'})

const mountNode = document.createElement('div')
document.body.appendChild(mountNode)

const unsubscribe = proxyStore.subscribe(() => {
  unsubscribe();
  render(
   <Provider store={proxyStore}>
     <App />
   </Provider>
   , document.getElementById('popup-app'));
});
WolffDev commented 5 years ago

As I said, I'm new to react/redux. I did some rubberduck debugging, and found an error in my code - it has been starring at me all day. I forgot to read props correctly in App.js:

// App.js
const mapStateToProps = state => {
  return {
    isAuthenticated: state.isAuthenticated,
    uid: state.uid
  }
}

Should be:

// App.js
const mapStateToProps = state => {
  return {
   // changed to state.auth.isAuthenticated
    isAuthenticated: state.auth.isAuthenticated,
   // changed to state.auth.uid
    uid: state.auth.uid
  }
}