<file_sep>import React from 'react';
import { connect } from 'react-redux';
import publicacionesReducer from '../../reducers/publicacionesReducer';
import publicacionesAction from '../Publicaciones';

const Tabla = (props) => {
  const ponerFilas = () => props.publicaciones.map((publicacion) => (
    <tr key={publicacion.id}>        
        <td>
          { publicacion.title }
        </td>
        <td>
          { publicacion.body }
        </td>        
      </tr>
    ));    

  return (
    <div>
      <table className="tabla">
            <thead>
              <tr>
                <th>Título</th>
                <th>Descripción</th>                
              </tr>
            </thead>
            <tbody>{ponerFilas()}</tbody>
          </table>
    </div>
  )
}

const mapStateToProps = (reducers) => {
  return reducers.publicacionesReducer;
}

export default connect(mapStateToProps, publicacionesAction) (Tabla);
<file_sep>import React from 'react';
import { connect } from 'react-redux';
import Spinner from '../General/Spinner';
import Fatal from '../General/Fatal';

const Comentarios = (props) => {
  if(props.com_error && !props.comentarios.length){
    return <Fatal mensaje={ props.com_error } />
  }

  if(props.com_cargando){
    return <Spinner/>
  }

  const ponerComentarios = () => (
    props.comentarios.map((comentario) => (
      <li>
        <b>
          <u>
            { comentario.email }
          </u>
        </b>
        <br/>
        { comentario.body }
      </li>
    ))
  );

  return (
    <ul>
      { ponerComentarios() }
    </ul>

  );
}

const mapStateToProps = ({publicacionesReducer}) => publicacionesReducer;

export default connect(mapStateToProps) (Comentarios);<file_sep>export const TRAER_TODAS = "tareas_traer_todos";
export const CARGANDO = "tareas_cargando";
export const ERROR = "tareas_error";
export const CAMBIO_USUARIO_ID = "cambio_usuario_id";
export const CAMBIO_USUARIO_TITULO = "cambio_usuario_titulo";
export const GUARDAR_TAREA = "guardar_tarea";
export const ACTUALIZAR = "actualizar_tarea";
export const LIMPIAR = "limpiar_tarea";
<file_sep>export const TRAER_TODOS = "usuarios_traer_todos";
export const CARGANDO = "usuarios_cargando";
export const ERROR = "usuarios_error";<file_sep>export const ACTUALIZAR = "publicaciones_actualizar";
export const CARGANDO = "publicaciones_cargando";
export const ERROR = "publicaciones_error";
export const COM_ACTUALIZAR = "comentarios_actualizar";
export const COM_CARGANDO = "comentarios_cargando";
export const COM_ERROR = "comentarios_error";<file_sep>import axios from 'axios';
import {
	CARGANDO,
	ERROR,
	ACTUALIZAR,
    COM_ACTUALIZAR,
    COM_ERROR, 
    COM_CARGANDO,
} from '../types/publicacionesTypes';
import * as usuariosTypes from '../types/usuariosTypes';

const { TRAER_TODOS: USUARIOS_TRAER_TODOS } = usuariosTypes;

export const traerPorUsuario = (key) => async (dispatch, getState) => {
    dispatch({
        type: CARGANDO,
    });

	let { usuarios } = getState().usuariosReducer;
	const { publicaciones } = getState().publicacionesReducer;
	const usuario_id = usuarios[key].id;

    try{
        const respuesta = await axios.get(`https://jsonplaceholder.typicode.com/posts?userId=${usuario_id}`);

        const nuevas = respuesta.data.map((publicacion) => ({
            ...publicacion,
            comentarios: [],
            abierto: false,
        }));

        const publicaciones_actualizadas = [
            ...publicaciones,
            nuevas,
        ];

        dispatch({
            type: ACTUALIZAR,
            payload: publicaciones_actualizadas
        });

        const publicaciones_key = publicaciones_actualizadas.length - 1;
        const usuarios_actualizados = [...usuarios];
        usuarios_actualizados[key] = {
            ...usuarios[key],
            publicaciones_key
        }

        dispatch({
            type: USUARIOS_TRAER_TODOS,
            payload: usuarios_actualizados
        });
    }catch(error){        
        dispatch({
            type:ERROR,
            payload: 'Publicaciones no disponibles.'
        });
    }
};

export const abrirCerrar = (pub_key, com_key) => ((dispatch, getState) => {
    const { publicaciones } = getState().publicacionesReducer;
    const seleccionada = publicaciones[pub_key][com_key];

    const actualizada = {
        ...seleccionada,
        abierto: !seleccionada.abierto,
    }

    const publicaciones_actualizadas = [...publicaciones];
    publicaciones_actualizadas[pub_key] = [
        ...publicaciones[pub_key]
    ]

    publicaciones_actualizadas[pub_key][com_key] = actualizada;

    dispatch({
        type: ACTUALIZAR,
        payload: publicaciones_actualizadas,
    });
});

export const traerComentarios = (pub_key, com_key) => async (dispatch, getState) => {
    dispatch({
        type: COM_CARGANDO,
    });

    const { publicaciones } = getState().publicacionesReducer;
    const seleccionada = publicaciones[pub_key][com_key];

    try{
        const respuesta = await axios.get(`https://jsonplaceholder.typicode.com/comments?postId=${seleccionada.id}`);

        const actualizada = {
            ...seleccionada,
            comentarios: respuesta.data,
        };
    
        const publicaciones_actualizadas = [...publicaciones];
        publicaciones_actualizadas[pub_key] = [
            ...publicaciones[pub_key]
        ]
    
        publicaciones_actualizadas[pub_key][com_key] = actualizada;
    
        dispatch({
            type: COM_ACTUALIZAR,
            payload: publicaciones_actualizadas,
        });
    }catch(error){        
        dispatch({
            type: COM_ERROR,
            payload: 'Comentarios no disponibles.'
        });
    }
};