How do I access store state in React Redux?
Solution 1
You should create separate component, which will be listening to state changes and updating on every state change:
import store from '../reducers/store';
class Items extends Component {
constructor(props) {
super(props);
this.state = {
items: [],
};
store.subscribe(() => {
// When state will be updated(in our case, when items will be fetched),
// we will update local component state and force component to rerender
// with new data.
this.setState({
items: store.getState().items;
});
});
}
render() {
return (
<div>
{this.state.items.map((item) => <p> {item.title} </p> )}
</div>
);
}
};
render(<Items />, document.getElementById('app'));
Solution 2
Import connect
from react-redux
and use it to connect the component with the state connect(mapStates,mapDispatch)(component)
import React from "react";
import { connect } from "react-redux";
const MyComponent = (props) => {
return (
<div>
<h1>{props.title}</h1>
</div>
);
}
}
Finally you need to map the states to the props to access them with this.props
const mapStateToProps = state => {
return {
title: state.title
};
};
export default connect(mapStateToProps)(MyComponent);
Only the states that you map will be accessible via props
Check out this answer: https://stackoverflow.com/a/36214059/4040563
For further reading : https://medium.com/@atomarranger/redux-mapstatetoprops-and-mapdispatchtoprops-shorthand-67d6cd78f132
Solution 3
You need to use Store.getState()
to get current state of your Store.
For more information about getState()
watch this short video.
Solution 4
All of the answers are from pre-hook era. You should use useSelector-hook to get the state from redux.
In your redux-reducer file or somewhere where you can import it easily:
import { useSelector } from 'react-redux'
export function useEmployees() {
return useSelector((state) => state.employees)
}
In your application code:
const { employees } = useEmployees()
More information on redux-hooks: https://react-redux.js.org/api/hooks to accomplish this goal.
Solution 5
You want to do more than just getState
. You want to react to changes in the store.
If you aren't using react-redux, you can do this:
function rerender() {
const state = store.getState();
render(
<div>
{ state.items.map((item) => <p> {item.title} </p> )}
</div>,
document.getElementById('app')
);
}
// subscribe to store
store.subscribe(rerender);
// do initial render
rerender();
// dispatch more actions and view will update
But better is to use react-redux. In this case you use the Provider like you mentioned, but then use connect to connect your component to the store.
Related videos on Youtube
Parkicism
Updated on March 27, 2021Comments
-
Parkicism about 3 years
I am just making a simple app to learn async with redux. I have gotten everything working, now I just want to display the actual state onto the web-page. Now, how do I actually access the store's state in the render method?
Here is my code (everything is in one page because I'm just learning):
const initialState = { fetching: false, fetched: false, items: [], error: null } const reducer = (state=initialState, action) => { switch (action.type) { case "REQUEST_PENDING": { return {...state, fetching: true}; } case "REQUEST_FULFILLED": { return { ...state, fetching: false, fetched: true, items: action.payload } } case "REQUEST_REJECTED": { return {...state, fetching: false, error: action.payload} } default: return state; } }; const middleware = applyMiddleware(promise(), thunk, logger()); const store = createStore(reducer, middleware); store.dispatch({ type: "REQUEST", payload: fetch('http://localhost:8000/list').then((res)=>res.json()) }); store.dispatch({ type: "REQUEST", payload: fetch('http://localhost:8000/list').then((res)=>res.json()) }); render( <Provider store={store}> <div> { this.props.items.map((item) => <p> {item.title} </p> )} </div> </Provider>, document.getElementById('app') );
So, in the render method of the state I want to list out all the
item.title
from the store.Thanks
-
ctrlplusb almost 8 yearsYou are almost there. You need to create a store connected component using the
react-redux
library. I highly recommend you polish your understanding of redux with the free course by the author: egghead.io/courses/getting-started-with-redux -
Kenny Worden almost 8 yearsYou do
store.getState()
to actually read the state from your store. redux.js.org/docs/api/Store.html#getState -
Parkicism almost 8 yearsThanks for the tutorial. I don't fully understand redux and this tutorial will help me out a lot.
-
-
Parkicism almost 8 yearsSo do I just change
this.props.items
tostore.getState().items
? When I did it, it's not outputting theitem.title
. -
semanser almost 8 years@Parkicism looks like you do not did initial rendering for your component. I highly recommend you to watch this course: egghead.io/courses/getting-started-with-redux
-
1ven almost 8 years@Parkicism this not displaying items, because when app is rendering first time, response from server is not received yet, you need to subscribe to store, to update component each time store changes.
-
Bang Dao over 7 years@1ven how to we get
store
variable defined here? -
1ven over 7 years@BangDao we can assume, that we are importing it from external file.
store
variable - it is redux store instance. -
N Sharma almost 7 yearsI have
let store = createStore(todoApp);
inindex.js
and I want to access thestore
insideApp.js
- What is the way of it ? -
Kermit_ice_tea over 6 yearsThe op asked specifically for React-Redux. Why provide solution for something other than the request?
-
Clay Banks about 6 years@BangDao You should include the
store
import for clarity. -
Pete Alvin about 6 yearsReferenceError Can't find variable: store
-
Pete Alvin about 6 yearsTypeError: undefined is not an object (evaluating '_redux.Store.getState')
-
Pete Alvin about 6 yearsReferenceError Can't find variable: store
-
semanser about 6 years@PeteAlvin Store is not a member of Redux variable. You should use store received from createStore(), like in this example: redux.js.org/api-reference/store#example
-
Pete Alvin about 6 years@semanser I'm trying to access the store in a view that's in an external .js file (not in the main App.js file where I call createStore()). So, I'm guessing I need to put the store in a "global object" that is shared across all views?
-
Pete Alvin about 6 years@semanser I thought the purpose of <Provider store={store}> was to be able to access the store from views, but I can't find any examples of how to actually retrieve it from a view in a separate file.
-
1ven about 6 years@PeteAlvin you need to have a redux store variable defined in your scope.
-
devssh almost 6 yearsAren't we supposed to access the reducer for that file instead of the entire store? Just access the itemsReducer instead to limit the state scope provided to items class
-
AnBisw over 5 years
import store from '../reducers/store';
. andstore.js
would containconst createStoreWithMiddleware = applyMiddleware(thunkMiddleware,promise)(createStore); export default createStoreWithMiddleware(reducers);
-
AnBisw over 5 yearsNOTE: This way, the props won't be accessible without invoking the action (defined in
mapDispatchToProps
). If you are attempting to obtain what's already in the store without dispatching another fetch cycle then you would have to use eithersubscribe
orgetState
on thestore
. -
Caio Mar almost 5 years@1ven or you could have added that line to your answer, much better than assuming
-
zloctb over 4 yearsgood article too coderwall.com/p/pafnew/redux-middleware-logger
-
staminna over 4 years@Annjawn can you provide a answer? 'applyMiddleware' is not defined no-undef 'thunkMiddleware' is not defined no-undef 'promise' is not defined no-undef 'createStore' is not defined no-undef 'reducers' is not defined no-undef
-
Ibrahim Farooq about 3 yearsWill this hook listen to the changes in the store? Will it update the local variable and re-render the component every time the store is changed?
-
Ilmari Kumpula about 3 years@IbrahimFarooq, yes, it does. It functions like a passed prop.
-
Yogi almost 3 yearsWhy we need another hook over useSelector()?
const employees = useSelector( state => state.employees)
-
Ilmari Kumpula almost 3 years@Yogi, you can totally use it without the extra-hook. I personally prefer to keep the Redux-specific useSelector only under Redux-folders. Secondary reason is that I find the useEmployees to be more expressive
-
Yogi almost 3 years@IlmariKumpula Thank you for the explanation! Thats good format to keep useSelector call functions under redux folder.
-
Emile ASTIH almost 2 years@IlmariKumpula you don't need to do anything in your reducer, you can simply
import {useSelector} from react-redux
in any functional component and access the state directly:const employees = useSelector((state) => state.employees)
.