I am using react-redux actions for app level state changes.
but not all components should be rendered when certain actions are triggered.
how can I check which action was triggered from any rendering React component?
Use redux-logger to log all the actions triggered in your dev tools console.
https://www.npmjs.com/package/redux-logger
It's a middle-ware so you 'll have to add it like so in your store:
/* ...import main reducer from wherever */
import createLogger from 'redux-logger';
import { createStore, applyMiddleware } from 'redux';
const logger = createLogger();
const store = createStore(
reducer,
applyMiddleware(/*..all the other middleares,*/ logger)
);
.
Bonus tip: You could integrate redux-devtools.
It adds a side dock to your site that tracks all the actions. See screen shot below:
Related
I was using redux developer tools in my application and When I opened the redux dev tools for having a look at the states there it showed undefined whereas my application is working perfectly fine. I think there is some mistake in my store code. I am attaching the code below.
import {legacy_createStore , composer} from 'redux'
import reducer from './reducerFn'
const composerEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSER__ || composer ;
export const store = legacy_createStore(reducer , composerEnhancer());
I have tried everything I searched on web. Could you please pin point the error in my code.
While it's not a direct answer: you're using an outdated style of Redux setup code there. Today you should be using the configureStore API from our official Redux Toolkit package, which already does all of that Redux DevTools setup work for you automatically.
All you need is:
import { configureStore } from "#reduxjs/toolkit";
import rootReducer from "./reducerFn";
const store = configureStore({
reducer: rootReducer
})
and that will do the Redux DevTools setup for you:
https://redux.js.org/tutorials/essentials/part-2-app-structure#creating-the-redux-store
https://redux.js.org/tutorials/fundamentals/part-8-modern-redux#using-configurestore
I found the error. It should be compose in place of composer everywhere.
import {legacy_createStore , compose} from 'redux'
import reducer from './reducerFn'
const composerEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose ;
export const store = legacy_createStore(reducer , composerEnhancer());
I am trying to build an e-commerce store app in React with Moltin JS. Everytime I try to upload it to Heroku, I get a blank page or an error. The error said that it could not resolve "redux-logger". I have tried re-downloading redux logger and also npm install. I still get the same error message. I've also tried NPM update. It works fine when I launch it from my VS Code.
github docs
Heroku Page
// import the ability to modify browser history within our router
import createHistory from 'history/createBrowserHistory';
// import our logger for redux
import { createLogger } from 'redux-logger';
// import a library to handle async with redux
import thunk from 'redux-thunk';
// import the redux parts needed to start our store
import { createStore, applyMiddleware, compose } from 'redux';
// import the middleware for using react router with redux
import { routerMiddleware } from 'react-router-redux';
// import the already combined reducers for redux to use
import rootReducer from './ducks';
// import moltin API wrapper for use with Redux
import * as api from './moltin';
// create and export history for router
export const history = createHistory();
// combine the middlewares we're using into a constant so that it can be used by our store
const middleware = [thunk.withExtraArgument(api), routerMiddleware(history)];
// declare any enhancers here
const enhancers = [];
// use Redux devtools if available in development
if (process.env.NODE_ENV === 'development') {
const devToolsExtension = window.devToolsExtension;
if (typeof devToolsExtension === 'function') {
enhancers.push(devToolsExtension());
}
middleware.push(createLogger());
}
// compose our middleware
const composedEnhancers = compose(applyMiddleware(...middleware), ...enhancers);
// create our redux store using our reducers and our middleware, and export it for use in index.js
const store = createStore(rootReducer, composedEnhancers);
export default store;
The trick is that Heroku installs only production dependencies on deployment by default, so the ones that are listed under dependencies key of you package.json by running npm install --production.
Move dependencies that are crucial to your app running - like redux-logger - from devDependencies to dependencies and that should solve your problem.
devDependencies are meant for things that support you in development, but are not required for the production copy of your app to run, like testing modules, for example.
I'm completely new with sagas.
Recently I was experimenting with an infrastructure for my future projects, including react-router v4 and sagas.
Well following the Beginner tutorial of sagas and some investigation on the matter i create an approximation, the idea is to make every connected component to redux to be it's own "micro universe" and have it own reducer, and, of course it own sagas file.
Ok, go with the code, here is the base structure of a component folder and the src folder:
src/
+components/
+foo-component/
-actions.js
-constants.js
-defaultState.js
-index.js
-reducer.js
-sagas.js
-App.js
-index.js
-rootReducer.js
-rootSagas.js
-store.js
Now, this is my sagas.js file fir foo-component, im creating the worker saga and the watcher saga, then i export them as an array to use in the rootSagas.js:
import { put, takeEvery } from 'redux-saga/effects'
import { COUNT } from './actions'
// Worker count
function* count() {
yield put({ type: COUNT })
}
// Watcher helloSaga
function* watchCount() {
yield takeEvery(COUNT, count)
}
const CounterSagas = [
count(),
watchCount()
]
export default CounterSagas
In the rootSagas.js file i get this sagas and export a single entry point which yield's all sagas at once:
import { all } from 'redux-saga/effects'
// sagas
import CounterSagas from './components/counter/sagas'
// run all
export default function* rootSagas() {
yield all([
// decompose
...CounterSagas,
])
}
Finally, in the store config the sagas are initiated:
import { compose, applyMiddleware, createStore } from 'redux'
import createSagaMiddleware from 'redux-saga'
import rootReducer from './rootReducer'
import rootSagas from './rootSagas'
let store
const sagaMiddleware = createSagaMiddleware()
if (process.env.NODE_ENV === 'production') {
store = createStore(
rootReducer,
applyMiddleware(sagaMiddleware)
)
} else {
store = createStore(
rootReducer,
compose(
applyMiddleware(sagaMiddleware),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
)
}
sagaMiddleware.run(rootSagas)
export default store
export const action = (type, payload) => store.dispatch({type, payload})
Ok, with this i have two problems:
The counter saga is fired one time automatically (not when the event is fired by a button).
When i fire the action COUNT, the browser run into a infinite loop and get blocked:
Error: An error was thrown inside one of your components, but React doesn't know what it was. This is likely due to browser flakiness. React does its best to preserve the "Pause on exceptions" behavior of the DevTools, which requires some DEV-mode only tricks. It's possible that these don't work in your browser. Try triggering the error in production mode, or switching to a modern browser. If you suspect that this is actually an issue with React, please file an issue.
I know, this is my inexperience talking out, so can anyone give me some guidance?
Thanks
Solved! the problem was in the middleware.run(sagas), removing it all works perfectly.
By removing middleware.run(sagas) the saga will actually be disabled. In fact the issue is that when you dispatch the action it will go to saga middleware and in the middleware we use put method(after watch) instead of dispatch and that will cause infinitely dispatch the same action. The problem will be solved by rename the action type or saga action type in takeEvery method first argument, they shouldn't be same!! like this:
// Watcher helloSaga
function* watchCount() {
yield takeEvery(A_COUNT, count)
}
I am trying to use the remote React Native Debugger for my project. I have installed React-Native-Debugger on my Mac with $ brew update && brew cask install react-native-debugger. Then I added Remote-redux-devtools package with npm install --save-dev remote-redux-devtools
My createStore code looks like this atm.
import { createStore, applyMiddleware } from 'redux'
import { composeWithDevTools } from 'remote-redux-devtools'
import thunk from 'redux-thunk'
/* some other imports */
const composeEnhancers = composeWithDevTools({ realtime: true, port: 8000 })
export default createStore(rootReducer, composeEnhancers(
applyMiddleware(thunk.withExtraArgument(api), logger, firebaseSave)
))
Console output works just fine, but it is not picking up on the actions or redux state. Am I missing a step? Why isn't it picking up redux?
https://github.com/zalmoxisus/remote-redux-devtools
https://github.com/jhen0409/react-native-debugger
Here's the solution I used in order to make the redux states visible on the react-native-debugger:
Let's suppose That I have a redux reducer called uiReducer:
const rootReducer = combineReducers({
ui: uiReducer
});
let composeEnhancers = compose;
if (__DEV__) {
composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
}
const store = createStore(rootReducer, composeEnhancers(applyMiddleware(ReduxThunk)));
Please don't forget to import your reducer, and also the following imports from redux, react-redux and redux-thunk :
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux';
import ReduxThunk from 'redux-thunk';
Now, your state if visible in the debugger :
I hope it's helpful !
Thanks,
Add redux devtools extension to your createStore
export default createStore(rootReducer, composeEnhancers(
applyMiddleware(thunk.withExtraArgument(api), logger, firebaseSave)
),window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
For more informations : https://github.com/zalmoxisus/redux-devtools-extension
I got the same problem where i thought the react native debugger is working fine,
E.g.
react native debugger's mapper is working fine, it is pulling out my project file/directory at the source.
Console output is working fine.
But i don't see any redux being picking up.
After some trials and errors, i found out i have to turn the JS Dev Mode on my android emulator.
Steps: Ctrl + M -> Dev Setting -> Check JS Dev Mode -> Reload
I noticed that along with this, I couldn't see my sources in Developer tools which lead me to realise that I need to do this
On the IOS Simulator
Cmd + D > Debug JS Remotely worked for me
I got a big problem for my project and cannot continue without that.
I have 2 screens : for example one for main page and another for second page.
So, there are 2 sections in my Navigation Drawer.
In main page, I save state into my store and get this:
object: {
fruits: ['apple', 'orange', 'banana'],
drinks: ['mojito', 'colar']
}
I want to access to the store of mainPage so in my second page I did :
store.getState().
And I got
object: {
fruits: [],
drinks: []
}
So I got the same state but it's empty. I don't understand why. If you have any ideas. I can maybe later show you more my code if necessary.
My store :
import { createStore, applyMiddleware } from 'redux';
import logger from 'redux-logger';
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'remote-redux-devtools';
import reducer from '../reducers';
const middleware = applyMiddleware(thunk, logger);
export default function configureStore(initialState) {
const store = createStore(
reducer,
initialState,
middleware
);
return store;
};
For each component, there are a container? Or only one container for all components? I don't really understand that. Sorry I'm new to React-Native, Redux and navigation drawer. It's hard for me to make them works all together..
Maybe the problem is in connect() but I connected them together normally
Sorry it's a little late and hard for me to say anything without seeing your reducers. Within your mainPage, you need to dispatch actions which will trigger a concat to the fruits and drinks array. You can also move your store declaration outside the function declaration and export it. Importing and calling it in other screens will allow you to have access to it, but this isn't the recommended way. The standard way is to call mapStateToProps method and connect that to your component.