1
resposta

TypeError: Cannot read property 'map' of undefined

Estou com problema com redux saga, não estou conseguindo listar os funcionarios, ja tentei de vários formas mas não obtive êxito . Acredito que o erro é seja porque estou usando paginação..

Pagina de fucionarios

import React, { Component } from 'react';
import PropTypes from 'prop-types';

import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import FuncionariosActions from '../../store/ducks/funcionarios';

import Button from '../../styles/components/Button';

import { Container, Table } from './styles';

class Funcionario extends Component {
  static propTypes = {
    getFuncionariosRequest: PropTypes.func.isRequired 
  };

  componentDidMount() {
    const { getFuncionariosRequest } = this.props;

    getFuncionariosRequest();

    console.log(this.props);
  }

  render() {
    const { funcionarios } = this.props;

    console.log(funcionarios);

    return (
      <Container>
        <header>
          <h1>Funcionarios</h1>
          <div>
            <Button onClick={() => {}}>+ Novo</Button>
          </div>
        </header>
        <Table>
          <table>
            <thead>
              <th>Nome</th>
              <th>Endereço</th>
              <th>Cidade</th>
              <th>Ação</th>
            </thead>
            <tbody>
              {funcionarios.data.map((funcionario) => (
                <tr key={funcionario.id}>
                  <td>{funcionario.name}</td>
                  <td>{funcionario.endereco}</td>
                  <td>{funcionario.cidade}</td>
                  <td>
                    <Button onClick={() => {}}>Editar</Button>
                    <Button color="danger" onClick={() => {}}>
                      Excluir
                    </Button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </Table>
      </Container>
    );
  }
}
const mapStateToProps = (state) => ({
  funcionarios: state.funcionarios.data,
});

const mapDispatchToProps = (dispatch) => bindActionCreators(FuncionariosActions, dispatch);

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

Duck de funcionario

import { createReducer, createActions } from 'reduxsauce';
import Immutable from 'seamless-immutable';

const { Types, Creators } = createActions({
  getFuncionariosRequest: null,
  getFuncionariosSuccess: ['data'],
});

export const FuncionariosTypes = Types;
export default Creators;

export const INITIAL_STATE = Immutable({
  data: [],
});

export const getSuccess = (state, { data }) => state.merge({ data });

export const reducer = createReducer(INITIAL_STATE, {
  [Types.GET_FUNCIONARIOS_SUCCESS]: getSuccess,
});

Index do duck

import { combineReducers } from 'redux';
import { connectRouter } from 'connected-react-router';

import { reducer as toastr } from 'react-redux-toastr';
import { reducer as auth } from './auth';
import { reducer as funcionarios } from './funcionarios';

export default (history) => combineReducers({
  auth,
  toastr,
  funcionarios,
  router: connectRouter(history),
});

Saga de funcionarios

import { call, put } from 'redux-saga/effects';
import api from '../../services/api';

import FuncionariosActions from '../ducks/funcionarios';

export function* getFuncionarios() {
  const response = yield call(api.get, 'funcionarios');

  // console.log(response.data);

  yield put(FuncionariosActions.getFuncionariosSuccess(response.data));
}

Index do saga

import { call, put } from 'redux-saga/effects';
import api from '../../services/api';

import FuncionariosActions from '../ducks/funcionarios';

export function* getFuncionarios() {
  const response = yield call(api.get, 'funcionarios');

  // console.log(response.data);

  yield put(FuncionariosActions.getFuncionariosSuccess(response.data));
}
1 resposta

Eu faço de uma forma um pouco diferente. Ao olhar o seu código, eu achei um problema no Duck de funcionários. A linha que chamou a minha atenção foi esta:

export const getSuccess = (state, { data }) => state.merge({ data });

Se eu entendi corretamente o "{data}", você quer pegar a propriedade "data" que for enviada como parâmetro. Se você enviar o "response", tudo bem, o data, vai existir (se houver sucesso na comunicação). Se você passar como parâmetro "response.data", deve dar errado (já que o data não vai existir).

Em relação aos Sagas, eu costumo fazer assim:

INDEX DO SAGA

import { all, takeLatest } from "redux-saga/effects";
import FuncionariosActions from "../ducks/funcionarios";
import getFuncionarios from "./funcionarios";

export default function* rootSaga() {
  yield all([
takeLatest(FuncionariosActions.getFuncionariosRequest, getFuncionarios)
  ]);
}

SAGA DE FUNCIONARIOS

import { call, put } from 'redux-saga/effects';
import api from '../../services/api';
import FuncionariosActions from '../ducks/funcionarios';

export function* getFuncionarios() {
  const response = yield call(api.get, 'funcionarios');
 // console.log(response.data);
  yield put(FuncionariosActions.getFuncionariosSuccess(response));
}