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
Related
I am new in redux. trying some simple code to implement which will update some initial value.when i click on add/minus, it prints " Received NaN for the children attribute. If this is expected, cast the value to a string",
I am sharing my code below:
code in counterSlice:
import { createSlice } from "#reduxjs/toolkit";
const initialState = {
counter : 0
}
export const counterSlice = createSlice({
name : 'counter',
initialState,
reducers:{
increment : (state) =>{
state.count += 1;
},
decrement : (state) =>{
state.count -= 1;
}
}
})
export const { increment , decrement } = counterSlice.actions;
export default counterSlice.reducer;
code from store.js
import { configureStore } from "#reduxjs/toolkit";
import counterReducer from "../feature/counter/counterSlice"
export const store = configureStore({
reducer : {
counter : counterReducer,
}
});
Counter.js
import React from 'react';
import { useSelector , useDispatch } from 'react-redux';
import {increment , decrement } from './counterSlice';
const Counter = () => {
const count = useSelector((state) => state.counter.count);
const dispatch = useDispatch();
return (
<section>
<p style={{fontSize:"40px",textAlign:"center"}}>{count}</p>
<div style={{display:"flex",flexDirection:"column",width:"50%",margin:"0 auto"}}>
<button style={{marginBottom:"5px"}} onClick=
{()=>dispatch(increment())}>Add</button>
<button onClick={() => dispatch(decrement())}>Minus</button>
</div>
</section>
);
};
export default Counter;
from index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { store } from './app/store.js';
import { Provider } from 'react-redux';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
reportWebVitals();
Hi guys i was setting up redux in my react native project but facing some issues while setup even though i am pretty sure i haven't used getState till now but as ssons as app runs i get error
TypeError: store.getState is not a function. (In 'store.getState()',
'store.getState' is undefined)
my code is as
reducers / hireducer.js
import { HI } from "../constants";
const initialState = {
count: 0,
};
const countReducer = (state = initialState, action) => {
switch (action.type) {
case HI:
return {
...state,
count: action.payload,
};
default:
return state;
}
};
export default countReducer;
reducers / index.js
import { combineReducers } from "redux";
import hiReducer from "./hireducer.js";
export default combineReducers({
hi: hiReducer,
});
store / configStore
import { createStore } from "redux";
import reducers from "../reducers/index";
const configureStore = () => {
return createStore(reducers);
};
export default configureStore;
App.js
import "react-native-gesture-handler";
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import AuthNavigator from "./navigations/AuthNavigation";
import { withHOC } from "./index.js";
function App() {
return (
<NavigationContainer>
<AuthNavigator />
</NavigationContainer>
);
}
export default withHOC(App);
index.js
import React from "react";
import { Provider } from "react-redux";
import configStore from "./redux/store/configStore";
export const withHOC = (App) => (props) => {
return (
<Provider store={configStore}>
<App {...props} />
</Provider>
);
};
even though if i normally wrap in without providing store i still get the same error
Your configStore returns a function instead of a store object.
So you rather call the function in your app like
<Provider store={configStore()}>
<App {...props} />
</Provider>
Or you create a store object from configStore like
const configureStore = () => {
return createStore(reducers);
};
export default configureStore();
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 to Redux and was learning how to use it with React. Basically, I did everything correctlyin terms of setting up Redux with react app but when I click on button increment I expect displaying counter to increment by one. But when I do that nothing happens and, certainly, I have checked dispatch and action being sent but basically all is ok. Thus I truly need your help guys here is the code I am using:
index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import registerServiceWorker from "./registerServiceWorker";
import { createStore } from "redux";
import reducer from "./store/reducer";
import { Provider } from "react-redux";
const store = createStore(reducer);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
registerServiceWorker();
reducer.js
const initialState = {
counter: 0
};
const reducer = (state = initialState, action) => {
if (action.type === "INCREMENT") {
return { counter: state.counter + 1 };
}
return state;
};
export default reducer;
counter.js
import React, { Component } from "react";
import { connect } from "react-redux";
import CounterControl from "../../components/CounterControl/CounterControl";
import CounterOutput from "../../components/CounterOutput/CounterOutput";
class Counter extends Component {
render() {
return (
<div>
<CounterOutput value={this.props.ctr} />
<CounterControl
label="Increment"
clicked={() => this.props.onIncrement}
/>
</div>
);
}
}
const mapStateToProps = state => {
return { ctr: state.counter };
};
const mapDispatchToProps = dispatch => {
return {
onIncrement: () => dispatch({ type: "INCREMENT" })
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(Counter);
Did you register your reducer with store?
If not, please do that.
I believe this thing should not return string:
const mapStateToProps = state => {
return { ctr: state.counter };
};
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
});