How do I access store state in React Redux?

242,121

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.

Share:
242,121

Related videos on Youtube

Parkicism
Author by

Parkicism

Updated on March 27, 2021

Comments

  • Parkicism
    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
      ctrlplusb almost 8 years
      You 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
      Kenny Worden almost 8 years
      You do store.getState() to actually read the state from your store. redux.js.org/docs/api/Store.html#getState
    • Parkicism
      Parkicism almost 8 years
      Thanks for the tutorial. I don't fully understand redux and this tutorial will help me out a lot.
  • Parkicism
    Parkicism almost 8 years
    So do I just change this.props.items to store.getState().items? When I did it, it's not outputting the item.title.
  • semanser
    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
    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
    Bang Dao over 7 years
    @1ven how to we get store variable defined here?
  • 1ven
    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
    N Sharma almost 7 years
    I have let store = createStore(todoApp); in index.js and I want to access the store inside App.js - What is the way of it ?
  • Kermit_ice_tea
    Kermit_ice_tea over 6 years
    The op asked specifically for React-Redux. Why provide solution for something other than the request?
  • Clay Banks
    Clay Banks about 6 years
    @BangDao You should include the store import for clarity.
  • Pete Alvin
    Pete Alvin about 6 years
    ReferenceError Can't find variable: store
  • Pete Alvin
    Pete Alvin about 6 years
    TypeError: undefined is not an object (evaluating '_redux.Store.getState')
  • Pete Alvin
    Pete Alvin about 6 years
    ReferenceError Can't find variable: store
  • semanser
    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
    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
    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
    1ven about 6 years
    @PeteAlvin you need to have a redux store variable defined in your scope.
  • devssh
    devssh almost 6 years
    Aren'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
    AnBisw over 5 years
    import store from '../reducers/store'; . and store.js would contain const createStoreWithMiddleware = applyMiddleware(thunkMiddleware,promise)(createStore); export default createStoreWithMiddleware(reducers);
  • AnBisw
    AnBisw over 5 years
    NOTE: 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 either subscribe or getState on the store.
  • Caio Mar
    Caio Mar almost 5 years
    @1ven or you could have added that line to your answer, much better than assuming
  • zloctb
    zloctb over 4 years
  • staminna
    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
    Ibrahim Farooq about 3 years
    Will 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
    Ilmari Kumpula about 3 years
    @IbrahimFarooq, yes, it does. It functions like a passed prop.
  • Yogi
    Yogi almost 3 years
    Why we need another hook over useSelector()? const employees = useSelector( state => state.employees)
  • Ilmari Kumpula
    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
    Yogi almost 3 years
    @IlmariKumpula Thank you for the explanation! Thats good format to keep useSelector call functions under redux folder.
  • Emile ASTIH
    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).