A
A
Andrey Ka2019-10-31 19:16:42
React
Andrey Ka, 2019-10-31 19:16:42

How to link data from redux to a component?

Hello, I'm in trouble, I'm studying redax and something goes wrong ...
In short, you need to get data from the server during initialization. I created actions, reducers and the store connected all this to the component, but he (the component) does not want to see what is there. The redax itself works fine, added midelver in the kosolka, everything is displayed correctly, all data is picked up from the server.
I will give a listing:
app.js

import rootReducer from './redux/reducers';
import { createLogger } from 'redux-logger';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import thunkMiddleware from 'redux-thunk'

const loggerMiddleware = createLogger();
const store = createStore(
    rootReducer,
    applyMiddleware(
        thunkMiddleware,
        loggerMiddleware
    )
);

const App = () =>  {
    return (
        <Provider store={store}>
                    <BrowserRouter basename={process.env.PUBLIC_URL}>
                        <Switch>
                            ...
                        </Switch>
                    </BrowserRouter>
        </Provider>
    );
};

export default App;

actions.js
spoiler

export const fetchChannelsPending = () => {
    return {
        type: types.FETCH_CHANNELS_PENDING,
        pending: true
    }
};

export const fetchChannelsSuccess = (channels) => {
    return {
        type: types.FETCH_CHANNELS_SUCCESS,
        channels: channels
    }
};

export const fetchChannelsError = (error) => {
    return {
        type: types.FETCH_CHANNELS_ERROR,
        error: error
    }
};


reducers.js
spoiler

import {
    FETCH_CHANNELS_ERROR, FETCH_CHANNELS_SUCCESS, FETCH_CHANNELS_PENDING
} from '../types';

const initialState = {
    pending: false,
    channels: [],
    error: null
};

export function channelsReducer(state = initialState, action) {
    switch(action.type) {
        case FETCH_CHANNELS_PENDING:
            
            return {
                ...state,
                pending: true
            };
            
        case FETCH_CHANNELS_SUCCESS:
            return {
                ...state,
                pending: false,
                channels: action.properties
            };
            
        case FETCH_CHANNELS_ERROR:
            
            return {
                ...state,
                pending: false,
                error: action.error
            };
            
        default:
            return state;
    }
}

export const getChannels = state => state.channels;
export const getChannelsPending = state => state.pending;
export const getChannelsError = state => state.error;


the component itself
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import fetchChannelsAction from './fetchChannels';
import { getChannelsError, getChannels, getChannelsPending } from '../../redux/reducers';

....

class ChannelList extends React.Component {

    componentDidMount() {
        let ch = this.props.fetchChannels(); // сам фетч выполняется
        console.log(ch); //undefined!!!!
    }

    renderChannels(channels) {...}
    
    ...


    render() {
        const { channels, pending } = this.props;

        // pending is undefined!
        if (pending) {
            return <ChannelPlaceholders count={5} />
        }

        return <>render channels here</>
   }
}

const mapStateToProps = state => ({
    error: getChannelsError(state),
    channels: getChannels(state),
    pending: getChannelsPending(state)
});

const mapDispatchToProps = dispatch => bindActionCreators({
    fetchChannels: fetchChannelsAction
}, dispatch);

export default connect(mapStateToProps, mapDispatchToProps)(ChannelList);

Sorry for the long listing, but what am I doing wrong?
here is another fetch.js it works fine, returns data but still
spoiler

const fetchChannels = () => {
    return dispatch => {
        dispatch(fetchChannelsPending());

        fetch('/url/api/channels')
            .then(res => res.json())
            .then(res => {
                if(res.error) {
                    throw(res.error);
                }

                dispatch(fetchChannelsSuccess(res));

                return res;
            })
            .catch(error => {
                dispatch(fetchChannelsError(error));
            })
    }
};

export default fetchChannels;

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Andrey Ka, 2019-10-31
@lacky_exception

In general, it is not clear why it does not work

const rootReducer =  combineReducers({
    channelsReducer, theDefaultReducer
});

Why doesn't it merge the reducers?
Got it, thanks :)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question