React-redux error: Uncaught Type Error _store_index_js__WEBPACK_IMPORTED_MODULE_2_is not a function - javascript

I am a newbie to Redux. I am trying a counter using redux but when I try to increase or decrease the counter using the increment/decrement buttons, I encounter this error:
Uncaught TypeError: _store_index_js__WEBPACK_IMPORTED_MODULE_2__.default.increment is not a function
at increment (App.js:10:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
at invokeGuardedCallback (react-dom.development.js:4277:1)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4291:1)
at executeDispatch (react-dom.development.js:9041:1)
at processDispatchQueueItemsInOrder (react-dom.development.js:9073:1)
at processDispatchQueue (react-dom.development.js:9086:1)
at dispatchEventsForPlugins (react-dom.development.js:9097:1)
at react-dom.development.js:9288:1
The state of the counter value does not change.
App.js
import { useSelector, useDispatch } from 'react-redux';
import './App.css';
import actions from './store/index.js';
function App() {
const counter = useSelector((state) => state.counter);
const dispatch = useDispatch();
const increment = ()=> {
dispatch(actions.increment());
}
const decrement = () => {
dispatch(actions.decrement());
}
const addBy = () => {
dispatch(actions.addBy(10))
}
return (
<div>
<h1>Counter App</h1>
<h2>{counter}</h2>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
<button onClick={addBy}>Add By 10</button>
</div>
);
}
index.js
import { configureStore, createSlice } from '#reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState : { counter: 0 },
reducers: {
increment(state, action) {
state.counter++;
},
decrement(state, action) {
state.counter--;
},
addBy(state, action) {
state.counter += action.payload;
}
}
})
export const actions = counterSlice.actions;
const store = configureStore({
reducer: counterSlice.reducer
})
export default store;
What am I missing? Your help is highly appreciated.

Should be
import { actions } from './store/index.js';

Related

TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator)

What I'm doing wrong. Below is my code.
// Imports
import { getAuth, signInWithPopup, GoogleAuthProvider } from "firebase/auth";
import { app } from "../../firebase.config";
import { useStateValue } from "../../context/StateProvider";
import { actionType } from "../../context/Reducer";
const firebaseAuth = getAuth(app);
const googleAuthProvider = new GoogleAuthProvider();
const [{user}, dispatch] = useStateValue();
const [isMenu, setIsMenu] = useState(false);
const login = async () => {
// const response = await signInWithPopup(firebaseAuth, googleAuthProvider);
// console.log(response);
if (!user) {
const {
user: { refreshToken, providerData },
} = await signInWithPopup(firebaseAuth, googleAuthProvider);
dispatch({
type: actionType.SET_USER,
user: providerData[0],
});
localStorage.setItem("user", JSON.stringify(providerData[0]));
} else {
setIsMenu(!isMenu);
}
};
// StateProvider.js
import React, {createContext , useContext, useReducer } from 'react';
export const StateContext = createContext();
export const StateProvider = ({Reducer,InitialState,children}) => (
<StateContext.Provider value = {useReducer(Reducer,InitialState)} > {children} </StateContext.Provider>
)
export const useStateValue = () => useContext(StateContext);
// reducer.js
export const actionType = {
SET_USER : 'SET_USER'
}
export const Reducer = (state, action) => {
// console.log(action);
switch(action.type) {
case actionType.SET_USER:
return {
...state,
user: action.user,
};
default:
return state;
}
}
// InitialState.js
import { fetchUser } from '../utils/fetchUserFromLocalStorage';
const userInfo = fetchUser();
export const InitialState = {
user : userInfo
}
// Error I'm getting
Header.jsx:31 Uncaught TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
at Header (Header.jsx:31:1)
at renderWithHooks (react-dom.development.js:16305:1)
at mountIndeterminateComponent (react-dom.development.js:20074:1)
at beginWork (react-dom.development.js:21587:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
at invokeGuardedCallback (react-dom.development.js:4277:1)
at beginWork$1 (react-dom.development.js:27451:1)
at performUnitOfWork (react-dom.development.js:26557:1)
at workLoopSync (react-dom.development.js:26466:1)
I had imported every thing perfectly also used it coorect way. My page isn't rendering anything. It is compiled perfectly with 0 error. Error i'm getting is typeerror but i didn't see any type erro. Please help me.

useSelector Returning Undefined object

I am trying to store users fetched by random users api and trying to dispatch it to my store i have store users with an empty array, when i am trying to get users using useSelector i am getting an undefined object.
Here is my store.js:
import { configureStore } from "#reduxjs/toolkit";
import counterReducer from "../features/counter/counterSlice";
import userReducer from "../features/users/userSlice";
export const store = configureStore({
reducer: {
counter: counterReducer,
user: userReducer,
},
});
Here is userSlice.js
import { createSlice } from "#reduxjs/toolkit";
export const userSlice = createSlice({
name: "users",
initialState: {
userArray: [],
},
reducers: {
getUsers: (state, action) => {
state.userArray = action.payload;
}
}
})
export const { getUsers } = userSlice.actions;
export const selectUsers = (state) => state.users.userArray;
export default userSlice.reducer;
Here is App.js
import logo from './logo.svg';
import './App.css';
import {useSelector, useDispatch } from 'react-redux';
import { getUsers, selectUsers } from './features/users/userSlice';
function App() {
const dispatch = useDispatch();
const users = useSelector(selectUsers);
const fetchUsers = async () => {
fetch("https://gorest.co.in/public/v2/users")
.then((response) => response.json())
.then((data) => {
console.log("data=====", data);
dispatch(getUsers(data));
});
};
return (
<div className="App">
<header className="App-header">
<button onClick={fetchUsers}>Get Users</button>
{users.length > 0 &&
users.map((user) => {
<li>user.name</li>;
})}
</header>
</div>
);
}
export default App;
you are mixing up state.user and state.users
either rename user in configureStore to users or use state.user.userArray

problem connecting multiple container components to redux store

I'm having trouble connecting my container components to the redux store, I'm not sure exactly where the connection is supposed to happen, whether in the container component or the component that will be dispatching an action. currently, my index.js looks like this
import React from "react";
import reactDOM from "react-dom";
import App from "./app.jsx";
import storeFactory from "./store";
import { Provider } from 'react-redux';
const store = storeFactory();
reactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("app")
);
currently, my store factory function looks like this
import rootReducer from "../reducers";
import { createStore, applyMiddleware } from "redux";
import { fetchProductInformation } from "../actions";
const storeData = {
productInformation: {}
};
const storeFactory = (initialState = storeData) => {
applyMiddleware(fetchProductInformation)(createStore)(
rootReducer,
localStorage["redux-store"]
? JSON.parse(localStorage["redux-store"])
: storeData
);
};
export default storeFactory;
my container component is
import SearchBar from '../components/searchbar.jsx';
import Nutrients from "../components/Nutrients.jsx";
import { fetchProductInformation } from '../actions';
import { connect } from 'react-redux';
const newSearch = (props) => (
<SearchBar
className="searchbar searchbar_welcome"
onNewProduct={( name ) => (props.fetchProductInformation(name))}
/>
)
const productInformation = (props) => {
const { nutrients, name } = props;
return nutrients.length > 1 ?
(
<div>
<newSearch />
<h3>{name}</h3>
<hr/>
<Nutrients
className="nutrientInformation"
list={nutrients}
/>
</div>
)
: null
}
const mapStateToProps = ({nutrients, name}) => ({
nutrients,
name
});
const mapDispatchToProps = dispatch => ({
fetchProductInformation: name => {
dispatch(fetchProductInformation(name))
}
});
export const Search = connect(null, mapDispatchToProps)(newSearch);
export const productInfo = connect(mapStateToProps)(productInformation);
when i run the code i get the following error
Provider.js:19 Uncaught TypeError: Cannot read property 'getState' of undefined
at Provider.js:19
at mountMemo (react-dom.development.js:15669)
at Object.useMemo (react-dom.development.js:15891)
at useMemo (react.development.js:1592)
at Provider (Provider.js:18)
at renderWithHooks (react-dom.development.js:15108)
at mountIndeterminateComponent (react-dom.development.js:17342)
at beginWork$1 (react-dom.development.js:18486)
at HTMLUnknownElement.callCallback (react-dom.development.js:347)
at Object.invokeGuardedCallbackDev (react-dom.development.js:397)
react-dom.development.js:19814 The above error occurred in the <Provider> component:
in Provider
Consider adding an error boundary to your tree to customize error handling behavior.
Visit react-error-boundaries to learn more about error boundaries.
Provider.js:19 Uncaught TypeError: Cannot read property 'getState' of undefined
at Provider.js:19
at mountMemo (react-dom.development.js:15669)
at Object.useMemo (react-dom.development.js:15891)
at useMemo (react.development.js:1592)
at Provider (Provider.js:18)
at renderWithHooks (react-dom.development.js:15108)
at mountIndeterminateComponent (react-dom.development.js:17342)
at beginWork$1 (react-dom.development.js:18486)
at HTMLUnknownElement.callCallback (react-dom.development.js:347)
at Object.invokeGuardedCallbackDev (react-dom.development.js:397)
from the errors shown i dont know exactly what the error is as it seems to be comming from the provider.js..
your code has some bug. here are fixed code.
import SearchBar from '../components/searchbar.jsx';
import Nutrients from "../components/Nutrients.jsx";
import { fetchProductInformation } from '../actions';
import { connect } from 'react-redux';
const newSearch = (props) => (
<SearchBar
className="searchbar searchbar_welcome"
onNewProduct={( name ) => (props.fetchProductInformation(name))}
/>
)
const productInformation = (props) => {
const { nutrients, name } = props;
return nutrients.length > 1 ?
(
<div>
<newSearch />
<h3>{name}</h3>
<hr/>
<Nutrients
className="nutrientInformation"
list={nutrients}
/>
</div>
)
: null
}
const mapStateToProps = ({nutrients, name}) => ({
nutrients,
name
});
const mapDispatchToProps = dispatch => ({
fetchProductInformation: name => {
dispatch(fetchProductInformation(name))
}
});
export const Search = connect(null, mapDispatchToProps)(newSearch);
export const productInfo = connect(mapStateToProps)(productInformation)
store.js
import rootReducer from "../reducers";
import { createStore } from "redux";
const storeData = {
productInformation: {}
};
const initialStore = localStorage["redux-store"] ? JSON.parse(localStorage["redux-store"]) : storeData;
const store = createStore(rootReducer, initialStore);
export default store;
index.js
import store from "./store";
...
<Provider store={store}>
...

React with redux

I am following the tutorial on linked in for react with Redux and Next.js. the code is working fine until I added Redux. I cannot understand the error below, it does not give me much info. Can some one explain to me where is the issue.
the tutorial did come with Exercise files but even they have the same issue. It could be something in my setup perhaps.
No page context
Error: No page context
at Function._callee$ (C:\learnings\SSR\node_modules\next-redux-wrapper\lib\index.js:164:23)
at tryCatch (C:\learnings\SSR\node_modules\regenerator-runtime\runtime.js:62:40)
at Generator.invoke [as _invoke] (C:\learnings\SSR\node_modules\regenerator-runtime\runtime.js:288:22)
at Generator.prototype.(anonymous function) [as next] (C:\learnings\SSR\node_modules\regenerator-runtime\runtime.js:114:21)
at asyncGeneratorStep (C:\learnings\SSR\node_modules\next-redux-wrapper\lib\index.js:18:103)
at _next (C:\learnings\SSR\node_modules\next-redux-wrapper\lib\index.js:20:194)
at C:\learnings\SSR\node_modules\next-redux-wrapper\lib\index.js:20:364
at new Promise (<anonymous>)
at Function.<anonymous> (C:\learnings\SSR\node_modules\next-redux-wrapper\lib\index.js:20:97)
at Function.getInitialProps (C:\learnings\SSR\node_modules\next-redux-wrapper\lib\index.js:205:22)
at _callee$ (C:\learnings\SSR\node_modules\next\dist\lib\utils.js:86:30)
at tryCatch (C:\learnings\SSR\node_modules\regenerator-runtime\runtime.js:62:40)
at Generator.invoke [as _invoke] (C:\learnings\SSR\node_modules\regenerator-runtime\runtime.js:288:22)
at Generator.prototype.(anonymous function) [as next] (C:\learnings\SSR\node_modules\regenerator-runtime\runtime.js:114:21)
at asyncGeneratorStep (C:\learnings\SSR\node_modules\#babel\runtime-corejs2\helpers\asyncToGenerator.js:5:24)
at _next (C:\learnings\SSR\node_modules\#babel\runtime-corejs2\helpers\asyncToGenerator.js:27:9)
My Index.js looks like this
import React from 'react';
import { bindActionCreators } from 'redux';
import { initStore, initialPosters, addItem } from '../store';
import withRedux from 'next-redux-wrapper';
import './index.css';
import Poster from './Poster';
class Index extends React.Component {
static async getInitialProps ({ store }) {
store.dispatch(initialPosters());
}
render () {
return (
<div className="App">
<header className="App-header">
<img src="/static/logo.png"
className="static-logo" alt="logo"
/>
</header>
<div className="Grid">
{
this.props.Posters.map((Poster) => (
<Poster key={Poster.id} />
))
}
</div>
</div>
)
}
};
const mapDispatchToProps = (dispatch) => {
return {
initialPosters: bindActionCreators(initialPosters, dispatch),
addItem: bindActionCreators(addItem, dispatch)
}
}
const mapStateToProps = (state) => {
return {
Posters: state.Posters,
}
}
export default withRedux(initStore, mapStateToProps, mapDispatchToProps)(Index);
my store.js
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunkMiddleware from 'redux-thunk';
import data from './data/data.json';
// initial state
const startState = {
posters: []
}
// Actions
export const initialposters = () => {
return {
type: 'INITIALPOSTERS',
posters: data
}
}
export const addItem = (item) => {
return {
type: 'ADD',
item
}
}
// reducers
export const reducer = (state = initialState, action) => {
switch (action.type) {
case 'INITIALPOSTERS':
return {
posters: action.posters,
}
case 'ADD':
return {
...state,
posters: [...state.posters, action.item]
}
default: return state
}
}
// create store
export const initStore = (initialState = startState) => {
return createStore(reducer, initialState, composeWithDevTools(applyMiddleware(thunkMiddleware)));
}
the Poster.js
import './Poster.css';
const Poster = (props) => (
<div className="Poster">
<div className="front">
<img src="/static/product.jpg" alt="Avatar" className="Poster-image" />
<div className="container">
<h3>A product <span className="price">$24.99</span></h3>
<p>A description </p>
</div>
</div>
</div>
);
export default Poster;
The error stack trace suggests line 164 in index.js in next-redux-wrapper which ends up here
case 2:
if (appCtx.ctx) {
_context.next = 4;
break;
}
throw new Error('No page context');
I am very new to react and redux so i am not able to make anything out of it. the good thing is its not working so there is opportunity to solve something here :D
it is a paid tutorial ; so not sure if this link would work for people.
https://www.lynda.com/React-js-tutorials/React-Server-Side-Rendering/679641-2.html

async redux. Error: modifiers may not emit actions

I keep encountering what appears to be a parallel async redux error. At a high level I am trying to dispatch a bunch of async actions that fetch assets from urls.
I originally tried redux-thunk middleware and was encountering the same error. I have since moved to a "listener" style middleware which looks like:
// listener-middleware.js
// taken from https://medium.com/#alexandereardon/the-middleware-listener-pattern-better-asynchronous-actions-in-redux-16164fb6186f
export default (...listeners) => store => next => action => {
// listeners are provided with a picture
// of the world before the action is applied
const preActionState = store.getState();
// release the action to reducers before
// firing additional actions
next(action);
// always async
setTimeout(() => {
// can have multiple listeners listening
// against the same action.type
listeners.forEach(listener => {
if (listener[action.type]) {
listener[action.type](action, store.dispatch, preActionState);
}
});
});
};
The asset listener then looks like:
import { assetsFetchBinary, assetsReceiveBinary } from '../assets/actions.js';
export default {
[assetsFetchBinary.toString()]: (action, dispatch, state) => {
const assetPath = state.config.assetPath + '/' + action.payload.assetName;
if(!state.assets[action.payload.assetName]){
fetch(assetPath)
.then(response => response.arrayBuffer())
.then(arrayBuffer => {
return dispatch(assetsReceiveBinary(action.payload.assetName, arrayBuffer))
});
}
},
}
The store configuration and applyMiddleware is:
import { createStore, applyMiddleware } from 'minidux'
import rootReducer from './rootReducer';
import { createLogger } from 'redux-logger';
import { routerMiddleware } from 'react-router-redux'
import { sceneTickAction } from './dsl/scene/actions.js';
import assetMiddleware from './dsl/assets/middleware.js';
import listenerMiddleware from './listener-middleware';
const logger = (initialState) => {
const predicate = (getState, action) => {
if(action.type === sceneTickAction.toString()){
return false;
}
return true;
}
return createLogger({predicate});
};
const getMiddleWare = (initialState, history) => {
const list = [];
if(initialState.system.role === 'client'){
const routerHistory = routerMiddleware(history);
list.push(routerHistory);
list.push(listenerMiddleware(assetMiddleware))
list.push(logger(initialState));
return list;
};
const configureStore = (initialState, history) => {
return createStore(
rootReducer(initialState),
initialState,
applyMiddleware.apply(this, getMiddleWare(initialState, history))
);
}
export default configureStore
The actions are straight forward
import { createAction } from 'redux-actions';
export const assetsReceiveBinary = createAction('#ASSETS/RECEIVE_BINARY')
export const assetsFetchBinary = createAction('#ASSETS/FETCH_BINARY')
and the Reducers:
import { handleActions } from 'redux-actions';
import { assetsFetchBinary, assetsReceiveBinary } from '../assets/actions.js';
export const assetReducer = (state, action) => handleActions({
[assetsFetchBinary]: (state, action) => {
if(state.assets[action.path]){ return state; }
return {
...state,
assets: {
...state.assets,
[action.path]: {}
}
}
},
[assetsReceiveBinary]: (state, action) => {
return {
...state,
assets: {
...state.assets,
[action.path]: {arrayBuffer: action.arrayBuffer}
}
}
}
}, state)(state, action);
export default assetReducer;
The stack trace is as follows:
createStore.js:27 Uncaught Error: modifiers may not emit actions
at dispatch (createStore.js:27)
at listener-middleware.js:10
at middleware.js:13
at Object.assetsFetchBinary (bindActionCreators.js:3)
at CharacterView.jsx:21
at Array.forEach (<anonymous>)
at CharacterView.componentDidUpdate (CharacterView.jsx:20)
at commitLifeCycles (react-dom.development.js:11517)
at commitAllLifeCycles (react-dom.development.js:12294)
at HTMLUnknownElement.callCallback (react-dom.development.js:1299)
at Object.invokeGuardedCallbackDev (react-dom.development.js:1338)
at invokeGuardedCallback (react-dom.development.js:1195)
at commitAllWork (react-dom.development.js:12415)
at workLoop (react-dom.development.js:12687)
at HTMLUnknownElement.callCallback (react-dom.development.js:1299)
at Object.invokeGuardedCallbackDev (react-dom.development.js:1338)
at invokeGuardedCallback (react-dom.development.js:1195)
at performWork (react-dom.development.js:12800)
at scheduleUpdateImpl (react-dom.development.js:13185)
at scheduleUpdate (react-dom.development.js:13124)
at Object.enqueueSetState (react-dom.development.js:9646)
at Connect../node_modules/react/cjs/react.development.js.ReactComponent.setState (react.development.js:
dispatch line 27 looks like:
function dispatch (action) {
if (!action || !isPlainObject(action)) throw new Error('action parameter is required and must be a plain object')
if (!action.type || typeof action.type !== 'string') throw new Error('type property of action is required and must be a string')
if (isEmitting) throw new Error('modifiers may not emit actions')
The action at that dispatch call looks like {type: "#ASSETS/FETCH_BINARY"}
Additionally, I invoke these actions in componentDidMount like the following:
class CharacterView extends Component {
componentDidUpdate(){
if(this.props.missingItemAssets){
this.props.missingItemAssets.forEach((assetName) => {
this.props.assetsFetchBinary(assetName);
});
}
}
If I wrap the dispatch calls in a 0 setTimeout it prevents the error.
class CharacterView extends Component {
componentDidUpdate(){
if(this.props.missingItemAssets){
setTimeout(() => {
this.props.missingItemAssets.forEach((assetName) => {
this.props.assetsFetchBinary(assetName);
});
}, 0)
}
}
You mentioned that you dispatch the actions in componentDidMount, but your example shows you're actually dispatching from componentDidUpdate.
class CharacterView extends Component {
componentDidUpdate(){ // <--- should be componentDidMount?
if(this.props.missingItemAssets){
this.props.missingItemAssets.forEach((assetName) => {
this.props.assetsFetchBinary(assetName);
});
}
}
}
This might be causing your problem, assuming your example in the question is accurate.

Categories

Resources