Hseleiro Hseleiro - 16 days ago 8
React JSX Question

React-Router - Show Details From a Specific ID

Im making a simple portfolio, using react-router.

I have a Index page "/" and a Works Page "trabalhos/" that display all of my works.

The objective is when i click the Show More Button on the Works Page, i want to go to a single page that displays only that work.

Im using

<Route path="trabalhos/:id" component={TrabalhosShow} />
to pass via props the id to my new page.

Now the objective is to show the details of that work.

Need Help.

Thanks

routes.js

import React from 'react';
import { Route, IndexRoute } from 'react-router';

import App from './components/app';
import Index from './components/index';
import Trabalhos from './containers/trabalhos';
import TrabalhosShow from './containers/trabalhos_show';

export default (
<Route path="/" component={App}>
<IndexRoute component={Index} />
<Route path="trabalhos" component={Trabalhos}/>
<Route path="trabalhos/:id" component={TrabalhosShow} />
</Route>
);


trabalhos.js (List of Works)

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';


class Trabalhos extends Component {


renderList(){

return this.props.trabalhos.map((trabalho) => {
return(

<li key={trabalho.id}>
<img src={trabalho.img} />
<p className="trabalho_titulo">{trabalho.title}</p>
<p className="trabalho_desc">{trabalho.descricao}</p>
<Link to={"trabalhos/" + trabalho.id}>
<span className="trabalho_saber_mais">Saber Mais</span>
</Link>
</li>

);
});
}


render(){

return (

<div>
<div className="trabalhos">
<div className="trabalhos_caixa">
<div className="row">
<div className="col-xs-12">
<ul className="no_pad">
{this.renderList()}
</ul>
</div>
</div>
</div>
</div>
</div>

);
}
}


function mapStateToProps(state){

return {

trabalhos: state.trabalho

};
}



export default connect(mapStateToProps)(Trabalhos);


trabalhos_show.js (Single Work)

import React, { Component } from 'react';


class TrabalhosShow extends Component {


render(){
return (


<div>
<div>Show post {this.props.params.id}</div>
</div>


);
}

}


export default TrabalhosShow;


reducer_trabalhos

export default function() {

return [

{ id: 1, title: 'Miristica', tec: "Wordpress-Woocommerce", descricao: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", img: 'http://feiraalternativa.pt/wp-content/uploads/2016/04/Miristica-Bio-Cosm%C3%A9tica.png'},
{ id: 2, title: 'Teste', tec: "Wordpress-Woocommerce", descricao: "Lorem ipsum dolor sit amet", img: 'https://pbs.twimg.com/profile_images/766360293953802240/kt0hiSmv.jpg'},

];

}


reducer Index.js

import { combineReducers } from 'redux';
import TrabalhoPortofolio from './reducer_trabalhos';

const rootReducer = combineReducers({
trabalho: TrabalhoPortofolio
});

export default rootReducer;


Thank You !

Answer

Connect your detail page to the redux store and filter it via the ID.

Your trabalhos_show.js should be as follows :

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

class TrabalhosShow extends Component {


    render(){
        let jobDetails = this.props.trabalhos.filter( t => t.id == this.props.params.id)[0];
        return (
                <div>
                    <img src={jobDetails.img} />
                    <p className="trabalho_titulo">{jobDetails.title}</p>
                    <p className="trabalho_desc">{jobDetails.descricao}</p>
                </div> 
            );
    }

}

function mapStateToProps(state){
   return {
       trabalhos: state.trabalho
   };
}

export default connect(mapStateToProps)(TrabalhosShow);

The other solution would be to add onClick event and pass the job details via browserHistory.

In trabalhos.js you should change your link to :

<span className="trabalho_saber_mais" onCLick={this.handleClick.bind(this, trabalho)}>Saber Mais</span>

It should look like this :

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link, browserHistory } from 'react-router';


class Trabalhos extends Component {
        handleClick(trabalho){
            browserHistory.push({
                pathname: "trabalhos/" + trabalho.id,
                state: {trabalhoDetails: trabalho}
            });
    }

    renderList(){

        return this.props.trabalhos.map((trabalho) => {
            return(

                <li key={trabalho.id}>                 
                        <img src={trabalho.img} />
                        <p className="trabalho_titulo">{trabalho.title}</p>
                        <p className="trabalho_desc">{trabalho.descricao}</p>
                        <span className="trabalho_saber_mais" onCLick={this.handleClick.bind(this, trabalho)}>Saber Mais</span>
                </li>

            );
        });
    }


    render(){

        return (

            <div>
                <div className="trabalhos">
                    <div className="trabalhos_caixa">
                        <div className="row">
                            <div className="col-xs-12">
                                <ul className="no_pad">
                                    {this.renderList()}
                                </ul>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

        );
    }
}


function mapStateToProps(state){

    return {

        trabalhos: state.trabalho

    };
}



export default connect(mapStateToProps)(Trabalhos);

And then in trabalhos_show.js you can use the state which you passed with browserHistory like :

let jobDetails = this.props.location.state.trabalhoDetails

And then you can get all what you have inside trabalho like :

let title = jobDetails.title;
let desctription = jobDetails.descricao;

Hope this helps.