1

I just started learning React and I feel I am facing a common problem most beginners will face. I am building a really simple React App at the moment. I am aiming to build a website with a navigation and some dynamic content that changes according to the navigation item that is clicked. However the content has always the same layout so the only part that needs to be changed is the data that is displayed in the content component.

I managed to build a working version however it feels wrong since it misses to update the content component. Instead I created for every page a new component (List.js and List2.js) that loads data from two differen files (data.js and data2.js). I am wondering now how I can just use one component (list.js) and always update its content based on the category that is clicked in the navigation. This is my current code:

App.js

import React, { Component } from 'react'
import List from '../components/List'
import Nav from '../components/Nav'
import data from '../src/data/data'

require ('../src/sass/App.scss');

    class App extends Component {

     render () {
        return (
        <div className="wrapper">
        <Nav />
        {this.props.children}



         </div>
        )
      }

    }

    export default App

routes.js

import React from 'react'
import { Route, IndexRoute } from 'react-router'
import App from '../components/App';
import List from '../components/List';
import List2 from '../components/List2';
import IndexPage from '../components/IndexPage';





const routes = (
  <Route path="/" component={App}>
    <IndexRoute component={IndexPage} />
    <Route path="/list1" component={List} />
    <Route path="/list2" component={List2}/>



  </Route>
);

export default routes;

List.js

import React, { Component } from 'react'
import Article from './Article'
require ('../src/sass/List.scss');
import data from '../src/data/data'

class List extends Component {

  render() {


    const listWebsites = data.map(websites => {

        return (
            <Article key={websites.id} name={websites.name} preview={websites.description} image={websites.image} />
            )
    })

    console.log('our data is:', this.props.data)
    return (
      <div className="wrapperList">
          {listWebsites}

        </div>
    )
  }

}

export default List

List2.js

import React, { Component } from 'react'
import Article from './Article'
require ('../src/sass/List.scss');
import data from '../src/data/data2'

class List extends Component {

  render() {


    const listWebsites = data.map(websites => {

        return (
            <Article key={websites.id} name={websites.name} preview={websites.description} image={websites.image} />
            )
    })

    console.log('our data is:', this.props.data)
    return (
      <div className="wrapperList">
          {listWebsites}

        </div>
    )
  }

}

export default List

Nav.js

import React, { Component } from 'react'
import { Link } from 'react-router';
import data from '../src/data/data'
require ('../src/sass/Nav.scss');

class Nav extends Component {

 render () {
    return (
    <div>
     <nav>
        <ul>
            <li><Link to="/list1" activeClassName="active">List1</Link></li>
            <li><Link to="/list2" activeClassName="active">List2</Link></li>


        </ul>
     </nav> 
     </div>
    )
  }

}

export default Nav

data.js (data2.js same structure)

const data = [
  {
    'id': '1',
     'name': 'Website1',
    'description': 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr ',
    'image': 'website1.png',

  },
  {
    'id': '2',
    'name': 'Website2',
    'description': 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr  ',
    'image': 'webstie2.jpg',

  },
  {
    'id': '3',
    'name': 'website3',
    'description': 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr ',
    'image': 'website3.jpg',

  }

export default data

Thanks for your help!

1 Answer 1

1

You could add a parameter in React Router with (code not tested):

const routes = (
  <Route path="/" component={App}>
    <IndexRoute component={IndexPage} />
    <Route path="/list1/:data" component={List} />    
  </Route>
);

Then, on the List component, React Router will add the parameters to a params property:

import React, { Component } from 'react'
import Article from './Article'
require ('../src/sass/List.scss');

class List extends Component {

  render() {

    //We could do this elswere depending on the requirements and 
    //how the data will be loaded (maybe use componentDidMount and the state)
    var data=[];
    if(this.props.params.data==="data1"){
      //Load data1 to data ... data=....
    }else{
      //Load other data  ... data=....
    }

    const listWebsites = data.map(websites => {

        return (
            <Article key={websites.id} name={websites.name} preview={websites.description} image={websites.image} />
            )
    })

    console.log('our data is:', this.props.data)
    return (
      <div className="wrapperList">
          {listWebsites}

        </div>
    )
  }

}

export default List

Finally you use it with:

    <li><Link to="/list/data1" activeClassName="active">List1</Link></li>
    <li><Link to="/list/data2" activeClassName="active">List2</Link></li>

Here is the documentation about this.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, seems like this is an option thats only possible for two navigation options, right?
Could you please explain me how to load the data1 to data and data2 to data? Is it not necessary to import the data anymore?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.