Go into your React project app folder and install following:
npm install --save redux react-redux



We will create app called Songs. useful image



To connect React with Redux, we will create two new components, Provider and Connect. Connect can communicate with Provider, which is at the top of hierarchy through contacts system. Contacts system allow parent component to communicate with any child component, even there is another component between them.

useful image

Structure

useful image

src/actions/index.js

We called this file index.js because when we then import it, we dont need to enter full path, we can specify only directory, it will automatically look for index.js.

//Action creator
export const selectSong = (song) => {
    //Return an action
    return {
        type: 'SONG_SELECTED',
        payload: song
    };
};



src/reducers/index.js

import { combineReducers } from 'redux';

const songsReducer = () => {
    return [
        {
            title: 'No Scrubs',
            duration: '4:05'
        },
        {
            title: 'Macarena',
            duration: '2:30'
        },
        {
            title: 'All Star',
            duration: '3:15'
        },
        {
            title: 'I want it that way',
            duration: '1:45'
        }
    ];
};

const selectedSongReducer = (selectedSong = null, action) => {
    if (action.type === 'SONG_SELECTED') {
        return action.payload;
    }
    return selectedSong;
}

export default combineReducers({
    songs: songsReducer,
    selectedSong: selectedSongReducer
});



src/components/SongList.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { selectSong } from '../actions';

class SongList extends Component {
    renderList() {
        return this.props.songs.map((song) => {
            return (
                <div className="item" key={song.title}>
                    <div className="right floated content">
                        <button
                            className="ui button primary"
                            onClick="{() => this.props.selectSong(song)}"
                        >
                            Select
                        </button>
                    </div>

                    <div className="content">{song.title}</div>
                </div>
            );
        });
    }

    render() {
        return <div className="ui divided list">{this.renderList()}</div>;
    }
}

//here we are getting data from redux store and sending it to react component, there will be available as this.props
const mapStateToProps = (state) => {
    return {
        songs: state.songs
    };
}

//we are passing selectSong as second argument
//connect function will take selectSong action creator and pass it to our component as prop
//connect function is calling dispatch behind the scenes, each time state is updated
export default connect(mapStateToProps, {
     selectSong: selectSong
})(SongList);



src/components/SongDetail.js

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

const SongDetail = (props) => {
    if (!props.song) {
        return <div>Select a song</div>
    }

    return (
        <div>
            {props.song.title}
            {props.song.duration}
        </div>
    );
}

const mapStateToProps = (state) => {
    return { song: state.selectedSong }
}

export default connect(mapStateToProps)(SongDetail);



src/components/App.js

import React from 'react';
import SongList from './SongList';
import SongDetail from './SongDetail';

const App = () => {
    return (
        <div>
            <SongList />
        </div>

        <div>
            <SongDetail />
        </div>
    );
};

export default App;



src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';

import App from './componentes/App';
import reducers from './reducers';

ReactDOM.render(
    <Provider store={createStore(reducers)}>
        <App />
    </Provider>,
    document.querySelector('#root'));





Step by Step

We first do action creator.

actions/index.js

export const selectSong = song => {
    return {
        type: 'SONG_SELECTED',
        payload: song
    };
};



Then we do reducers. One reducer will return list of all songs. Second reducer will allow to select specified song after user click on the button. At the top we will import redux library and combine all reducers together with combineReducers function. We will pass to combineReducers object. Keys of this object will be the keys which show up in inside our state object.

reducers/index.js

import { combineReducers } from 'redux';

const songsReducer = () => {
    return [
        {
            title: 'No Scrubs',
            duration: '4:05'
        },
        {
            title: 'Macarena',
            duration: '2:30'
        },
        {
            title: 'All Star',
            duration: '3:15'
        },
        {
            title: 'I want it that way',
            duration: '1:45'
        }
    ];
};

const selectedSongReducer = (selectedSong = null, action) => {
    if (action.type == 'SONG_SELECTED') {
        return action.payload;
    }

    return selectedSong;
};


export default combineReducers({
    songs: songsReducer,
    selectedSong: selectedSongReducer
});



Then we need to import Provider, createStore and reducers. We need also wrap <App/> with <Provider>.

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';

import App from './components/App';
import reducers from './reducers';

ReactDOM.render(
    <Provider store={createStore(reducers)}>
        <App />
    </Provider>,
    document.query('#root')
);



We now want to get list of songs into our SongList component. We will use connect for that.
mapStateToProps - we will take our state and map it to props, so state will be then available in props and we can use it SongList component.

components/SongList.js

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

class SongList extends React.Component {
    render() {
        console.log(this.props);   //we now see songs here
        return <div>SONGLIST</div>
    }
}

const mapStateToProps = (state) => {
    console.log(state);
    return {
        songs: state.songs     //songs will be now available in this.props in this component
    };
};

export default connect(mapStateToProps)(SongList);





Při práci s reduxem potkáme tři základní konstrukce: store, akci a reducer.

Store

Store je objekt ve kterém jsou uložena naše data. Store poskytuje tyto 3 základní metody, v jednoduchosti je síla.

store.getState() // vrací naše data (state)
store.subscribe(callback) // pokud chceme zjistit že se data změnila
store.dispatch(akce) // provádíme akci, která změní data ve Store uložená



Akce

Pokud chceme změnit data ve store, popíšeme tuto změnu pomocí jednoduchého objektu zvaného akce. Objekt akce má jediný povinný atribut jménem type, ten slouží pro identifikaci. Další atributy vyplníme libovolně dle potřeby. Jinak řečeno: akce musí být jednoznačně identifikovatelná a musí obsahovat všechna data nutná k jejímu provedení.

{
    type: "ADD_ITEM",
    text: "Nějaký úkol"
}



Reducer

Posledním dílem skládačky je reducer. Funkce kterou napíšeme a vložíme do store, aby bezpečně modifikovala data podle požadavků vyjádřených akcí. Reducer tedy čeká uvnitř store až zavoláme dispatch(akce) a jakmile se tak stane, store zavolá reducer a předá mu:

  • state – současná data aplikace
  • action – celý objekt akce tak, jak jsme jej vložili do volání dispatch() (akce obsahuje identifikaci ‘type’ a jakákoliv další data potřebná k provedení)