<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: KeithArogo</title>
    <description>The latest articles on DEV Community by KeithArogo (@keitharogo).</description>
    <link>https://dev.to/keitharogo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F877686%2F6fa67e79-c9c1-467a-9f3b-62115525aad2.jpeg</url>
      <title>DEV Community: KeithArogo</title>
      <link>https://dev.to/keitharogo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/keitharogo"/>
    <language>en</language>
    <item>
      <title>Dynamic Pages using React Router v6.3</title>
      <dc:creator>KeithArogo</dc:creator>
      <pubDate>Tue, 28 Jun 2022 17:06:23 +0000</pubDate>
      <link>https://dev.to/keitharogo/dynamic-pages-using-react-router-v63-42pk</link>
      <guid>https://dev.to/keitharogo/dynamic-pages-using-react-router-v63-42pk</guid>
      <description>&lt;p&gt;Dynamic pages and routes can be defined as pages that contain content relevant to them. An example of this could be a user’s profile page on a social media website. Social media platforms more often than not contain profile pages that display a user’s general information. Different users will have different information on their profiles but the overall structure stays the same, that is the essence of dynamic pages.&lt;/p&gt;

&lt;p&gt;Let's see how we can implement this in React. We'll be using the Ghibli API to get a list of films and we'll implement dynamic pages and routes for all of them. Clicking on the film will then take you to a dynamic page that displays more information about the said film. &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1
&lt;/h2&gt;

&lt;p&gt;Create a new React project using create-react-app. Also install React Router by running ‘npm install react-router-dom’ in your project folder via terminal. The react-router-dom package contains bindings for using React Router in web applications&lt;/p&gt;

&lt;p&gt;Open the App.js file and remove the default code and add the following;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import MoviePage from "./MoviePage";
import HomePage from "./HomePage";

const App = () =&amp;gt; {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Router&amp;gt;
        &amp;lt;Routes&amp;gt;
          &amp;lt;Route exact path="/" element={&amp;lt;HomePage /&amp;gt;} /&amp;gt;
          &amp;lt;Route path="/movie/:movieId" element={&amp;lt;MoviePage /&amp;gt;} /&amp;gt;
        &amp;lt;/Routes&amp;gt;
      &amp;lt;/Router&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default App;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2
&lt;/h2&gt;

&lt;p&gt;create another separate component called Homepage. This will be our homepage from where we'll call the Ghibli API to get film data. We've already defined a route for this component in App.js. Now let's go ahead and add in the API call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";


const HomePage = () =&amp;gt; {
    const [isLoading, setIsLoading] = useState(true);
    const [data, setData] = useState();

    useEffect(() =&amp;gt; {
      fetch("https://ghibliapi.herokuapp.com/films", {})
        .then((res) =&amp;gt; res.json())
        .then((response) =&amp;gt; {
          setData(response);
          setIsLoading(false);
        })
        .catch((error) =&amp;gt; console.log(error));
    }, []);

    console.log("Data!", data);

    return (
      &amp;lt;&amp;gt;
        {!isLoading &amp;amp;&amp;amp;
          data.map((movie) =&amp;gt; {
            return (
              &amp;lt;h5 key={movie.id}&amp;gt;
                &amp;lt;Link to={`/movie/${movie.id}`}&amp;gt;{movie.title}'s Page&amp;lt;/Link&amp;gt;
              &amp;lt;/h5&amp;gt;
            );
          })}
      &amp;lt;/&amp;gt;
    );
  };

  export default HomePage;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have two states, isLoading which could either be true or false should tell us whether we have received the data from the API or not.&lt;/p&gt;

&lt;p&gt;We use a useEffect hook to fetch data when the HomePage component renders. When we obtain the data from the API we set the value of isLoading to false and data to whatever JSON we get.&lt;/p&gt;

&lt;p&gt;Now, if you look at the jsx inside the HomePage component you'll see that we check the value of isLoading and if it's false, we map through the response data to render the names of the films.&lt;/p&gt;

&lt;p&gt;Run your app with ‘npm start’ and you should see the film names on  display.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3
&lt;/h2&gt;

&lt;p&gt;But, we don't just  want a list of movies, we also want separate pages with dynamic routes for each of them.&lt;/p&gt;

&lt;p&gt;So let's create another component called MoviePage which will fetch data from an API getting the details of each movie.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useEffect } from "react";
import { Link, useParams } from "react-router-dom";

const MoviePage = () =&amp;gt; {
  const { movieId } = useParams();
  const [isLoading, setIsLoading] = useState(true);
  const [data, setData] = useState();

  useEffect(() =&amp;gt; {
    fetch(`https://ghibliapi.herokuapp.com/films/${movieId}`, {})
      .then((res) =&amp;gt; res.json())
      .then((response) =&amp;gt; {
        setData(response);
        setIsLoading(false);
        console.log(`https://ghibliapi.herokuapp.com/films/${movieId}`);
      })
      .catch((error) =&amp;gt; console.log(error));
  }, [movieId]);
  console.log(data);

  return (
    &amp;lt;&amp;gt;
      {!isLoading &amp;amp;&amp;amp; (
        &amp;lt;&amp;gt;
          &amp;lt;h1&amp;gt;Title: {data.title}&amp;lt;/h1&amp;gt;
          &amp;lt;h2&amp;gt;Plot: {data.description}&amp;lt;/h2&amp;gt;
          &amp;lt;Link to="/"&amp;gt;Back to homepage&amp;lt;/Link&amp;gt;
        &amp;lt;/&amp;gt;
      )}
    &amp;lt;/&amp;gt;
  );
};

export default MoviePage;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have defined a MoviePage component which lists details about each person by getting data from the API in the same fashion as HomePage. We have also defined a new route for this component i.e, movie/:movieId. This is a bit different compared to our regular routes. Here we pass a parameter movieId through the route. That way a single component at that route can be dynamic based on that parameter.&lt;/p&gt;

&lt;p&gt;HomePage returns links to this dynamic route with the movie id as the route parameter.&lt;/p&gt;

&lt;p&gt;If you observe MoviePage closely, you'll realize that while the structure of it stays the same, all the content on the page is dependent on movieId i.e, the component is fully dynamic. &lt;/p&gt;

&lt;p&gt;The useParams hook returns an object of key/value pairs of the dynamic params from the current URL that were matched by the . Child routes inherit all params from their parent routes. useParams hook lets you access the parameters of the current route.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If you'd like to gain more insight into React Router, read the official docs,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://reactrouterdotcom.fly.dev/docs/en/v6"&gt;React Router Docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/keithowino6"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rJvAnNew--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.buymeacoffee.com/buttons/default-black.png" alt="Buy Me A Coffee" width="434" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Broken Links on Netlify React.js using React Router solution</title>
      <dc:creator>KeithArogo</dc:creator>
      <pubDate>Fri, 17 Jun 2022 13:59:46 +0000</pubDate>
      <link>https://dev.to/keitharogo/broken-links-on-netlify-reactjs-using-react-router-solution-42of</link>
      <guid>https://dev.to/keitharogo/broken-links-on-netlify-reactjs-using-react-router-solution-42of</guid>
      <description>&lt;h1&gt;
  
  
  react #reactrouter #netlify
&lt;/h1&gt;

&lt;p&gt;This solution is for anyone who has deployed a React Single Page Application using &lt;a href="https://www.netlify.com/"&gt;Netlify&lt;/a&gt;’s hosting services and ran into a ‘Page Not found’ error after refreshing any page that isn’t the default homepage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i0CkqKzu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jyqetcoqurnecfi49gcf.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i0CkqKzu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jyqetcoqurnecfi49gcf.PNG" alt="Image description" width="736" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You’re probably confused because the said issue does not occur when interacting with the App on the local host server, so what could have gone wrong?&lt;/p&gt;

&lt;p&gt;The reason is fairly simple but not too obvious, React Router is set up to handle routing on the browser/client-side. That said, refreshing the website on any page other than the root (all routes are specified at the root level) means that Netlify won’t understand how to handle the specific route.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution.
&lt;/h2&gt;

&lt;p&gt;The solution is to create a file and name it ‘&lt;em&gt;redirects’ to the root of our site inside the ‘public’ folder/directory _(path = ‘public/_redirects’)&lt;/em&gt; and type in/copy-paste the following;&lt;br&gt;
&lt;code&gt;/* /index.html 200&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1ElS5_aS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3qiuvj60iuj2h1abrofe.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1ElS5_aS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3qiuvj60iuj2h1abrofe.PNG" alt="Image description" width="633" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This works because Netlify offers a  &lt;a href="https://docs.netlify.com/routing/redirects/"&gt;_redirects&lt;/a&gt; file, which you can add to your codebase along with the rest of your files and folders. This will equip Netlify with the required information in order to handle URLs that are not handled on the browser.&lt;/p&gt;

&lt;p&gt;For more details, visit the official &lt;a href="https://docs.netlify.com/"&gt;Netlify documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/keithowino6"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rJvAnNew--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.buymeacoffee.com/buttons/default-black.png" alt="Buy Me A Coffee" width="434" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>netlify</category>
      <category>reactrouter</category>
    </item>
  </channel>
</rss>
