Efim Rozovsky
Efim Rozovsky

Reputation: 383

How to read redux state inside a component the right way?

I am having trouble understanding how to connect a component with my redux state(in the right way)

so far I tried using mapStateToProps, but have absolutely no idea where the data is stored afterwards, I even managed to get an instance inside the constructor, but it also feels wrong, in other components (which built in a strange way) I see programmers just pulling the the state out of thin air, but in my component(which is a class that extends 'component') I can only get the desired result by changing manually each change inside mapStateToProps.

the component where I try to get the state (check the comment inside mapStateToProps, that's what I kinda want)

import React, { Component } from "react";
import { connect } from "react-redux";
import {initCreate} from "../../actions" 

const mapDispatchToProps = dispatch => {
    return {
        initCreate: () => dispatch(initCreate())
    };
};
const mapStateToProps = state => {
    //this.state.toggleCreate = state.reduction.toggleCreate;  <= seems to work, but feels wrong? is this how it's done in react? 
    return state.reduction;
};
class CrudBar extends Component {
    constructor(reduction) {
        super();
        this.state = { toggleCreate: false};
        this.create = this.create.bind(this);
    }
    create() {
        this.props.initCreate();
        setTimeout(() => {
            console.log('state in component', this.state); // prints the state unchanged
        }, 1000);
    }

    render() {
        return (
            <div>
                <button onClick={this.create}>Create</button>
            </div>
        )
    }
}
const toolBar = connect(mapStateToProps, mapDispatchToProps)(CrudBar);
export default toolBar;

actions.js

export const addCategory = category => ({ type: "ADD_CATEGORY", payload: category });
export const initCreate = state => ({ type: "CRUDBAR_CREATE", payload: state });

my reducer:

const initialState = {
    toggleCreate: false,
};
const reductionReducer = (state = initialState, action) =>{
    switch (action.type) {
        case "CRUDBAR_CREATE":
        console.log('here') // printed
        setTimeout(() => {
            console.log('redux state', state); // prints the state changed
        }, 1000);
            return {
                toggleCreate: !state.toggleCreate,
            };
        default:
            return state;
    }
};
export default reductionReducer;

the code where the programmer pulls the state out of thin air:

import React from "react";
import { connect } from "react-redux";

const mapStateToProps = state => {
    return state.categories;
};

const CategoriesList = ({ categories }) => ( // I want something like this, to get the information and render accordingly
    <ul>
        {
             categories.map(el => (
            <li key={el.id}>
            {/* Name, Address, Coordinates, and Category. */}
               Name - {el.name}
            </li>
        )) }
    </ul>
);
const List = connect(mapStateToProps)(CategoriesList);
export default List;

I want the component to read the state out of redux, and I want to do it, in the right way, not some cheap trick that other programmers would have to dance around and cringe.

Upvotes: 0

Views: 1429

Answers (1)

Shmili Breuer
Shmili Breuer

Reputation: 4147

To use redux state you need to get it from the store and inject it to the components props.

The way you do it is by first creating a function which returns the pieces of redux state you need in the particular component like this

const mapStateToProps = ({pieceOfReduxState, anotherPieceOfReduxStete}) =>
    ({pieceOfReduxState, anotherPieceOfReduxStete})

This return 2 pieces of redux state

Then you inject it as the first argument to the connect function

connect(mapStateToProps)(ComponentName)

This will make the redux store available in your components props

Then just use it in your component by accessing this.props.pieceOfReduxState

Hope this helps.

Upvotes: 2

Related Questions