I am getting error "Expected the reducer to be a function.".
I am trying to add redux in my project .I create reducer but also getting error "Expected the reducer to be a function." .here is my code
https://codesandbox.io/s/k5Gp2gglx
import React from 'react';
import { render } from 'react-dom';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import {Provider} from 'react-redux';
import {combindReducer} from './reducers/index'
import Hello from './Hello';
const styles = {
fontFamily: 'sans-serif',
textAlign: 'center',
};
const App = () => (
<div style={styles}>
<Hello name="CodeSandbox" />
<h2>Start editing to see some magic happen {'\u2728'}</h2>
</div>
);
const store = createStore(combindReducer,
applyMiddleware(thunk)
);
render(
<Provider store ={store}>
<App />
</Provider>
, document.getElementById('root'));
combine reducer
import {combineReducers } from 'redux';
import {first_redux} from './topstories';
const combindReducer = combineReducers({
item: first_redux
})
export default combindReducer;
topstories
export default function(state = [], action) {
switch (action.type) {
case 'ADD_ITEM':
return [
...state,
action.payload
];
case 'DELETE_ITEM':
const index = state.indexOf(action.payload);
if (index === -1) {
return state;
}
return state.slice(0, index).concat(state.slice(index + 1));
case 'UPDATE_ITEM':
let newList = state.slice()
newList.splice(action.payload.index, 1, action.payload.item)
return newList;
default:
return state
}
}
since you're using default exports (not named exports), the import statements for your reducers should not have curly braces:
import combindReducer from './reducers/index';
and
import first_redux from './topstories';
https://codesandbox.io/s/L8RE3X5D4
Related
trying to make an option to change the color of text,border,background but i get the error state is not defined in the console.it says that state.options.text that i addressed in option page is not defined,
i checked the routing and it is Ok
option page
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import {textCH, borderCh, backgroundCh} from '../Utilities/options/theme'
function Options() {
const textcolor = useSelector((state)=>state.options.text)
console.log(textcolor);
return (
<div style={{ paddingLeft: '20px' }}>
<h1>OPTIONS</h1>
text color: <input type={'color'} />
border color: <input type={'color'} />
background color: <input type={'color'} />
</div>
)
}
export default Options
Reducer
import { createSlice } from '#reduxjs/toolkit'
const initialState = {
text:'#000000',
border:'#000000',
background:'#FFFFFF',
}
export const optionsSlice = createSlice({
name: 'options',
initialState,
reducers: {
textCH: (state,action) => {
state.text = action.payload
},
borderCh: (state,action) => {
state.border = action.payload
},
backgroundCh: (state, action) => {
state.background = action.payload
},
},
})
export const { textCH, borderCh, backgroundCh } = optionsSlice.actions
export default optionsSlice.reducer
Store file
import { configureStore } from '#reduxjs/toolkit'
import {optionsSlice} from './options/theme'
export const store = configureStore({
reducer: {
options: optionsSlice,
},
})
Console error:
Uncaught TypeError: state.options is undefined
textcolor Options.jsx:6
Provider setup:
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import {store} from "./Utilities/store";
import { Provider } from "react-redux";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<>
<Provider store={store}>
<App />
</Provider>
</>
);
You're importing the slice itself in the store.js, not reducer.
instead of calling the named function:
import {optionsSlice} from './options/theme'
we should call the default one:
import optionsSlice from './options/theme'
I have carefully gone through my code, nothing wrong with store, reducer function, Provider, but useSelector hook returns undefined in the App.js. Why does it return undefined?
redux.js
import {createStore} from 'redux'
const counterReducer = (state = {counter:0}, action)=>{
if(action.type ==='increment'){
return {counter:state.counter+1}
}
if(action.type ==='decrement'){
return{counter : state.counter-1}
}
}
const store = createStore(counterReducer);
export default store;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import store from '../src/store/redux'
import {Provider} from 'react-redux'
ReactDOM.render(
<Provider store = {store}>
<App />
</Provider>,
document.getElementById('root')
);
reportWebVitals();
App.js
import './App.css';
import {useSelector} from 'react-redux'
function App() {
const counter = useSelector(state=> state);
console.log(counter) //undefined
return (
<div></div>
);
}
export default App;
redux.js
import { createStore } from 'redux';
const counterReducer = (state = { counter: 0 }, action) => {
**// Updated previous if statement using switch statement**
switch (action.type) {
case 'increment':
return { ...state, counter: state.counter + 1 };
case 'decrement':
return { ...state, counter: state.counter - 1 };
default:
return { counter: 0 }; // you need to define a default value;
}
const store = createStore(counterReducer);
export default store;
app.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import './style.css';
export default function App() {
const counter = useSelector((state) => state.counter);
const dispatch = useDispatch();
console.log(counter);
return (
<div>
<h1>{counter}</h1>
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
</div>
);
}
Look at this code, we always need a default value when creating reducer. Using switch statement for this case I think safe.
you can see this solution: stackbllitz
I'm following this
https://react-redux.js.org/api/hooks
I get state undefined, i connected my store or i think i did. i dont know what is the issue. The reducer code is inconsequetial. I'm just trying to return anything to get some kind of helloo world. I have used react redux before.
//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './js/App';
import * as serviceWorker from './serviceWorker';
import { Provider } from 'react-redux';
import { createStore,} from 'redux';
import reducers from './js/reducers';
const store = createStore(reducers);
ReactDOM.render(
<Provider store={store}>
<React.StrictMode>
<App />
</React.StrictMode>
</Provider>,
document.getElementById('root')
);
//App.js
function App() {
const data = useSelector(state.myReducerData)
return (
<div>{data}</div>
);
}
export default App
//reducers/index.js
import { combineReducers } from 'redux';
import {OneReducer} from "./ExampleReducers"
const rootReducer = combineReducers({
myReducerData: OneReducer
});
export default rootReducer;
//ExampleReducers.js
import {EXAMPLES} from "../actions/types";
export function OneReducer (state = {}, action) {
switch (action.type) {
case EXAMPLES:
return action.payload
default:
return state
}
return state;
}
You're missing reducer initial state for one.
import { EXAMPLES } from "../actions/types";
// declare it here.
const initialState = {
data:[]
};
export function OneReducer(state = initialState, action) {
switch (action.type) {
case EXAMPLES:
return action.payload;
default:
return state;
}
return state;
}
and you can try this
const data = useSelector((state) => state.data) // refers to initial state data property
I am new with Redux and followed a tutorial on implementing redux in react. I'm having an issue that seems to be no value is being received in app.js from store.js's createStore function. Any ideas?
app.js
import React, { Component } from 'react';
import AppNavbar from './components/AppNavbar';
import ShoppingList from './components/ShoppingList';
import ItemModal from './components/ItemModal';
import { Container } from 'reactstrap';
import { Provider } from 'react-redux';
import store from './store';
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
class App extends Component {
render() {
return (
<Provider store={store}>
<div className="App">
<AppNavbar />
<Container>
<ItemModal />
<ShoppingList />
</Container>
</div>
</Provider>
);
}
}
export default App;
store.js
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
compose(
applyMiddleware(thunk)
)
);
export default store;
reducers folder
itemReducer.js - Just showing GET_ITEMS case
import {
GET_ITEMS,
ADD_ITEM,
DELETE_ITEM,
ITEMS_LOADING
} from '../actions/types';
const initialState = {
items: [],
loading: false
};
export default function(state = initialState, action) {
switch (action.type) {
case GET_ITEMS:
return {
...state,
items: action.payload,
loading: false
};
index.js
import { combineReducers } from 'redux';
import itemReducer from './itemReducer';
export default combineReducers({
item: itemReducer
});
Error:
TypeError: Cannot read property 'apply' of undefined
(anonymous function)
C://client/node_modules/redux/es/redux.js:523
return funcs.reduce(function (a, b) {
return function () {
return a(b.apply(undefined, arguments));
};
});
}
createStore
C://client/node_modules/redux/es/redux.js:87
throw new Error('Expected the enhancer to be a function.');
}
return enhancer(createStore)(reducer, preloadedState);
}
if (typeof reducer !== 'function') {
./src/store.js
C://client/src/store.js:9
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
compose(
That error is related to the Redux DevTools Chrome extension integration which enables you to view the Redux store visually in the browser. Installing Redux DevTools extension should do the trick. If you do not wish to use the extension, you can simply omit the following code to remove the integration with the extension:
,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
I am learning redux. I have written an application for the same, first time. I am not able to understand why data isnt being fetched from store. Is there anything wrong with my connect call? Please help.
I am getting error that contactsList is undefined while calling map below, although connect should fetch that list as per my understanding.
ContactCards.js
import React, { Component } from 'react';
import Card from './Card';
import { connect } from 'react-redux';
const CardList = ({ contactsList }) => {
const cardsArray = contactsList.map(contact => (
<Card
key={contact.id}
name={contact.name}
email={contact.email}
phone={contact.phone}
website={contact.website}
city={contact.address.city}
companyName={contact.company.name}
id={contact.id} />
));
return (
<div className="jumbotron">
<div className='card-columns'>
{cardsArray}
</div>
</div>
);
};
const mapStateToProps = state => {
return { contactsList: state.contactsList };
};
const ContactCards = connect(mapStateToProps)(CardList);
export default ContactCards;
Reducer dataReducer
import ContactsList from '../components/MockContactsList';
import {loadContacts, updateContacts} from '../Actions/CardActions';
const INITIAL_STATE = {
contactsList: ContactsList
};
const dataReducer = (state = INITIAL_STATE, action) => {
switch(action.type) {
case loadContacts:
return state;
case updateContacts:
const updatedItems = state.contactsList.map(item => {
if(item.id === action.id){
return { ...item, ...action.payload }
}
return item
})
return updatedItems;
default:
return state;
}
};
export default dataReducer;
App.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import registerServiceWorker from './registerServiceWorker';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import reducers from './reducers/index';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
const store = createStore(reducers, {});
ReactDOM.render(
<Provider store = {store}>
<App />
</Provider>
,document.getElementById('root'));
registerServiceWorker();
Reducers index.js
import { combineReducers } from 'redux';
import dataReducer from './dataReducer';
export default combineReducers({
dataReducer
});
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import registerServiceWorker from './registerServiceWorker';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import reducers from './reducers/index';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
const store = createStore(reducers, {});
ReactDOM.render(
<Provider store = {store}>
<App />
</Provider>
,document.getElementById('root'));
registerServiceWorker();
You must first access your reducer state (dataReducer) then its property:
const mapStateToProps = state => {
return { contactsList: state.dataReducer.contactsList };
};
In your store you have a key of dataReducer:
export default combineReducers({
dataReducer
});
But you're accessing it as contactsList here:
const mapStateToProps = state => {
return { contactsList: state.contactsList };
};
So you probably need to have that key in your store instead:
export default combineReducers({
contactsList: dataReducer
});