Import/export when using reducers in Redux-React Native - javascript

I'm studying Redux with React Native and I have an example like this:
reducer.js
import {combineReducers} from "redux";
import {HomeReducer as home} from "../routes/Home/modules/home";
const makeRootReducer = () => {
return combineReducers({
home
});
};
export default makeRootReducer;
createStore.js
import {createStore, applyMiddleware, compose} from 'redux';
import thunk from "redux-thunk";
import {createLogger} from 'redux-logger';
import makeRouteReducer from './reducer';
const log = createLogger({diff: true, collapsed: true});
export default (initialState = {}) => {
const middleware = [thunk, log];
const enhancers = [];
return store = createStore(
makeRouteReducer(),
initialState,
compose(
applyMiddleware(...middleware),
...enhancers
)
);
}
It works fine but I don't understand why I have to use export default in reducer.js.
When I try to use
// reducer.js
export makeRootReducer
and
// createStore.js
import {makeRouteReducer} from './reducer';
It didn't work.
Please help me by explaining it in detail.
Thank you very much.

You're talking about named exports and default exports...
Example of a named export:
export const someFunction = () => {
// some code here...
}
Now you can import this in another file like this:
import {someFumnction} from './nameOfFile'
But if you do:
export default function someFunction () {
// some code here...
}
That's a default export and you have to import it like this:
import someFunction from './nameOfFile'
In your example if you change this:
const makeRootReducer = () => {
return combineReducers({
home
});
};
export default makeRootReducer;
To this:
export const makeRootReducer = () => {
return combineReducers({
home
});
};
It will become a named export and not a default export and now you can do:
import {makeRootReducer} from....
Hope that clarifies... And here is more info

Related

TypeScript Redux

I started doing the typing of my redux and ran into such a problem, namely the typing of useSelector
Here is the hook I'm creating:
import {TypedUseSelectorHook, useSelector} from 'react-redux'
import {RootState} from '../store/create-reducer'
export const UseTypedSelector: TypedUseSelectorHook <RootState> = useSelector
And he returns me an error:
screen
How to solve this problem? For the second day I can't get off the ground, and using useSelector ((state: any) => state? .SESSION) is not an option.
Here is my side:
create-reducer:
import { combineReducers } from 'redux'
import { STATE } from '../session/types'
import { reducer } from '../session/reducers'
const rootReducer = (asyncReducers: object) => {
return (
combineReducers({
...asyncReducers,
[STATE]: reducer,
})
)
}
export default rootReducer
export type RootState = ReturnType<typeof rootReducer>
create-store:
import { applyMiddleware, compose, createStore } from 'redux'
import thunk from 'redux-thunk'
import persistStore from './persist-store'
import persistReducer from './persist-reducer'
const store = (initialState = {}) => {
const middlewares = [thunk]
const enhancers: Array<any> = []
const store = createStore(
persistReducer({}),
initialState,
compose(applyMiddleware(...middlewares), ...enhancers),
)
const persistor = persistStore(store)
return { store, persistor }
}
export default store
index:
export { default as createReducer } from './create-reducer'
export { default as createStore } from './create-store'
export { default as persistReducer } from './persist-reducer'
persist-reducer:
import { persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import createReducer from './create-reducer'
const persistConfig = { key: 'myproject', storage, whitelist: ['session'] }
const reducer = (asyncReducers: any) => persistReducer(persistConfig, createReducer(asyncReducers))
export default reducer
persist-store:
import { persistStore } from 'redux-persist'
const store = (store: any) => persistStore(store, null, () => {})
export default store

React Native Redux Reducer not working

I'm attempting to implement redux into a relatively simple app, however my actions don't seem to be triggering the reducers properly. Through console logging the action seems to be firing, but the respective reducer isn't being executed.
App.js:
import {Provider} from 'react-redux';
import configureStore from './src/config/configureStore.js';
const store = configureStore();
export default class App extends React.Component {
render() {
return (
<Provider store = {store}>
<RootStack />
</Provider>
);
}
}
configureStore.js:
import {createStore, applyMiddleware} from 'redux';
import reducers from '../reducers';
import thunk from 'redux-thunk';
export default function configureStore(initialState) {
const store = createStore (
reducers,
applyMiddleware(thunk)
);
return store;
}
actions/index.js:
export const saveRisk = (payload) => {
console.log('saved RISK!');
return (dispatch) => {
dispatch({type: 'risk_chosen',payload: payload});
}
}
reducers/index.js:
import { combineReducers } from 'redux';
import RiskReducer from './RiskReducer';
export default combineReducers({
risk_level: RiskReducer
});
RiskReducer.js
const INITIAL_STATE = {risk_level: false};
export default (risk = INITIAL_STATE, action) => {
if(action.type === 'risk_chosen') {
console.log('RISK REDUCER SUCCESSFUL')
return {
...risk, risk_level: action.payload
};
}
console.log('REDUCER RISK:');
console.log(risk);
return risk;
}
RiskTolerance.js (A child component within RootStack which is using redux):
import { connect } from 'react-redux';
import {saveRisk} from '../../actions'
#connect(state => ({risk_level: state.risk_level.risk_level}, {saveRisk}))
export default class RiskTolerance extends React.Component {
// ...
componentDidMount(){
console.log(this.props.risk_level);
// ^^returns undefined, despite the reducer initializing it to "false"
let riskVal = 'something'
this.props.saveRisk(riskVal)
}
// ...
}
EDIT: I have changed the initial value in the reducer to an appropriate object but my reducer is still not working after the action is called. Any ideas?
Thank you!
There is problem with initial state in your reducer. Make changes as shown below:
INITIAL_STATE = { risk_level: false }
Figured it out, when calling the action I needed to write:
this.props.dispatch(this.props.saveRisk(riskVal))
Thanks for your help everyone!

React.js Redux actions and reducers do not get initated

I am having an issue with my React-Redux app. I have created Redux action & reducer and connected them to my React component. However, it seems like it never gets to my Redux action & reducer.
I put "debugger" in my action and reducer but those debuggers never get initiated.
Could you please help me fix this issue?
Am I missing something here?
Here the current codes in the following files:
Here is the code for my app.js:
import React, { Component } from 'react';
import { render } from 'react-dom';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import ReduxPromise from 'redux-promise';
import rootReducer from './reducers';
import App from './components/index';
const createStoreWithMiddleware = applyMiddleware(thunk, ReduxPromise)(createStore);
render(
<Provider store={createStoreWithMiddleware(rootReducer)}>
<App />
</Provider>,
document.getElementById('app')
);
Here is my code for index.js:
As you can see below, I put a debugger in the "componentDidMount()", and when In run it, it gets to that point.
import React, { Component } from 'react';
import { render } from 'react-dom';
import { connect } from 'react-redux';
import * as AllNewsApiActions from '../actions/newsApiActions';
import '../../css/style.css';
class App extends Component {
componentDidMount() {
this.props.getNewsApi();
debugger;
}
render() {
return (
<div>
<p>Hello from react</p>
<p>Sample Testing</p>
</div>
);
}
}
const mapStateToProps = (state) => ({
newNews: state.newNews
});
export default connect(mapStateToProps, {
...AllNewsApiActions
})(App);
Here is my action:
import * as types from './newsTypes';
const API_KEY = "6c78608600354f199f3f13ddb0d1e71a";
export const getNewsApi = () => {
debugger;
return (dispatch, getState) => {
dispatch({
type: 'API_REQUEST',
options: {
method: 'GET',
endpoint: `https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=${API_KEY}`,
actionTypes: {
success: types.GET_NEWS_API_SUCCESS,
error: types.GET_NEWS_API_ERROR
}
}
});
}
}
Here is my reducer:
import * as types from '../actions/newsTypes';
const initialState = {
newNews: []
};
const getNewsAPIReducer = (state = initialState, action) => {
switch(action.type) {
case types.GET_NEWS_API_SUCCESS:
debugger;
return { ...state, newNews: action.data };
case types.GET_NEWS_API_ERROR:
debugger;
return { ...state, error: action.data };
default: {
return state;
};
};
};
export default getNewsAPIReducer;
Here is the index.js file in the reducer folder:
import { combineReducers } from 'redux';
import NewsApiReducer from './newsApiReducer.js';
const rootReducer = combineReducers({
newNews: NewsApiReducer
});
export default rootReducer;

Redux - Store doesn't work

I am a novice in Javascript and Redux, and I just created my first app based on this tutorial. I have a problem that the Store absolutely doesn't react to any dispatch call. I don't know if there is an error in the connection between Redux and React or in the store configuration itself.
Could you please help me with this problem?
This is snippes from my actions file where "addTodo" action is defined.
export const ADD_TODO = 'ADD_TODO';
let todoId = 0;
export const addTodo = (text) => ({
type: ADD_TODO,
id: todoId++,
text,
});
Below is my Store configuration.
import { createStore, applyMiddleware, compose } from 'redux';
import rootReducer from '../reducers';
import DevTools from '../containers/DevTools';
const enhancer = compose(
applyMiddleware(createLogger),
DevTools.instrument()
);
export default function configureStore(initialState) {
const store = createStore(rootReducer, initialState, enhancer);
if (module.hot) {
module.hot.accept('../reducers', () => {
const nextRootReducer = require('../reducers').default;
store.replaceReducer(nextRootReducer);
});
}
return store;
}
My index file where I try to call a dispatch function with "AddTodo" action creator. Similarly, I call this function in Redux containers, but it doesn't work for both.
import React from 'react';
import { render } from 'react-dom';
import configureStore from './store/configureStore';
import { addTodo } from './actions';
const store = configureStore();
store.subscribe(() =>
console.log(store.getState())
);
store.dispatch(addTodo('test'));
The whole project is placed on Github too. I will be thankful if you help me.
you forgot to invoke createLogger, try
const enhancer = compose(
applyMiddleware(createLogger())
...
);
webpackbin test

React + Redux-router = Uncaught Error: Expected the reducer to be a function

My code is working fine, but I have an annoying problem whenever I make a coding mistake and get a runtime error. For instance, in one of my JSX pages I did Date() instead of new Date() and instead of reporting the actual error, I got...
Uncaught Error: Expected the reducer to be a function.
Any error I make almost always shows up as this. It's being reported from createStore.js, which is in my configureStore.jsx code below.
Is there a way that I can get better error reporting that helps me identify the real problem? Any help or ideas are greatly appreciated!!!
Here's my setup for reference....
main.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { ReduxRouter } from 'redux-router';
import configureStore from './store/configureStore'
import routes from './routes';
const rootEl = document.getElementById('app-container');
const store = configureStore();
ReactDOM.render(
<div>
<Provider store={store}>
<ReduxRouter routes={routes} />
</Provider>
</div>
, rootEl
);
configureStore.jsx
import { createHashHistory } from 'history';
import { applyMiddleware, createStore, compose } from 'redux';
import { reduxReactRouter } from 'redux-router';
import thunk from 'redux-thunk';
import promiseMiddleware from 'redux-promise-middleware';
import rootReducer from '../reducers/rootReducer';
import routes from '../routes';
export default function configureStore(initialState = {}) {
const history = createHashHistory();
const middlewares = [
thunk,
promiseMiddleware({
promiseTypeSuffixes: ['PENDING','SUCCESS','ERROR']
})
];
const toolChain = [
applyMiddleware(...middlewares),
reduxReactRouter({
routes,
history
})
];
const store = compose(...toolChain)(createStore)(rootReducer, initialState);
if (module.hot) {
module.hot.accept('../reducers', () => {
const nextRootReducer = require('../reducers/rootReducer');
store.replaceReducer(nextRootReducer);
});
}
return store;
}
rootReducer.jsx
import { combineReducers } from 'redux';
import { routerStateReducer } from 'redux-router';
import siteReducer from './siteReducer';
const rootReducer = combineReducers({
router: routerStateReducer,
sites: siteReducer
});
export default rootReducer;
siteReducer.jsx
import {GET_SITES} from '../actions/siteActions';
const defaultState = {
isPending: null,
isSuccess: null,
isError: null,
error: null,
data: null
};
export default function siteReducer(state = defaultState, action) {
switch (action.type) {
case `${GET_SITES}_PENDING`:
return {
...defaultState,
isPending: true
};
case `${GET_SITES}_SUCCESS`:
return {
...defaultState,
isSuccess: true,
error: false,
data: action.payload
};
case `${GET_SITES}_ERROR`:
return {
...defaultState,
isError: true,
error: action.payload
};
default:
return state;
}
}
Change the following line:
const nextRootReducer = require('../reducers/rootReducer');
To:
const nextRootReducer = require('../reducers/rootReducer').default;
Use export const variable_name instead of const variable_name whenever you want to export that variable.
For ex: rootReducer.jsx should be re-written as
import { combineReducers } from 'redux';
import { routerStateReducer } from 'redux-router';
import siteReducer from './siteReducer';
export const rootReducer = combineReducers({
router: routerStateReducer,
sites: siteReducer
});
export default rootReducer;
Note the extra export specifier with const rootReducer
My issue was importing Store from the root reducer path rather than the actual bundled store root (with devtools on the window and root reducer, middleware being composed, etc).
import Store from '../../../src/state/Store/reducer';
changed to
import Store from '../../../src/state/Store';

Categories

Resources