whoknows
whoknows

Reputation: 197

React Load Component on Navigation

I am trying to fetch content from server on every Router.

Navigation.js

import { Component } from "react";
import { Link } from "react-router-dom";
export class Navigation extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      all_nav: [
        {
          menu_name: "News 1",
          menu_items_id: "31"
        },
        {
          menu_name: "News 2",
          menu_items_id: "32"
        },
        {
          menu_name: "News 3",
          menu_items_id: "33"
        }
      ]
    };
  }

  render() {
    return (
      <ul>
        {this.state.all_nav.map((name, key) => (
          <li key={key}>
            <Link to={`news/${name.menu_items_id}`}>{name.menu_name}</Link>
          </li>
        ))}
        <hr />
        <li>
          <Link to="/">Home</Link>
        </li>
      </ul>
    );
  }
}

Navigation.js contains list of navigation that is used to route the content.

Index.js

import React from "react";
import { render } from "react-dom";
import { BrowserRouter, Route, Switch, Link } from "react-router-dom";
import { App } from "./App";
import { NewsList } from "./NewsList";

window.React = React;

render(
  <BrowserRouter>
    <div>
      <Route exact path="/" title="App Title" render={props => <App />} />

      <Route path="/news/:filter" render={props => <NewsList {...props} />} />
    </div>
  </BrowserRouter>,
  document.getElementById("root")
);

NewsList.js

import { Component } from "react";
import {Navigation} from './Navigation'
export class NewsList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      post_record: []
    };
  }

  componentDidMount() {
    this.setState({ loading: true });
    // console.log(this.props.match.params.filter)
    Promise.all([
      fetch("https://binodgiri.com.np/api/news_listing.php", {
        method: "POST",
        headers: {
          Accept: "application/json"
        },
        body: JSON.stringify({
          param: this.props.match.params.filter
        })
      })
    ])
      .then(([all_post_api]) => Promise.all([all_post_api.json()]))
      .then(([post_data]) =>
        this.setState({
          loading: false,
          post_record: post_data
        })
      );
  }

  render() {
    return (
      <div>
        <h1>Hello Content</h1>
        {
          this.state.post_record.menu_name

        }
        <hr />
        <Navigation />
      </div>
    );
  }
}

NewsList.js is main rendering section, according to :filter id the content should be fetched from server "https://binodgiri.com.np/api/news_listing.php"

What I really want to do is::

If I click News 1 or anyother News at first. It renders perfectly. And if I want to Navigation to News 2 or other Nothing Happens

Here is the sandbox link : https://codesandbox.io/s/vykxvp17j7

Thank-you in advance.

Upvotes: 0

Views: 625

Answers (1)

Shashidhara
Shashidhara

Reputation: 683

You should add this logic. Since componentDidMount is already mounted on first link click, it wont be called second time, hence you need to add following lifecycle function. (This is the quick fix, you can also rearrange the your logic for better performance.)

componentDidUpdate(prevProps) {
    if (this.props.match.params.filter !== prevProps.match.params.filter) {
      Promise.all([
       fetch("https://binodgiri.com.np/api/news_listing.php", {
      method: "POST",
      headers: {
        Accept: "application/json"
      },
      body: JSON.stringify({
        param: this.props.match.params.filter
      })
    })
  ])
    .then(([all_post_api]) => Promise.all([all_post_api.json()]))
    .then(([post_data]) =>
      this.setState({
        loading: false,
        post_record: post_data
      })
    );    
   }
}

In Navigation.js

<Link to={`/news/${name.menu_items_id}`}>{name.menu_name}</Link>

Upvotes: 1

Related Questions