Using APIs in a React Template - javascript

I am learning the ropes of React and JavaScript. I started by grabbing a free template I found from GitHub. After creating a few other pages, I connected the app to a Django back end and created a model with two entries.
The objective is to be able to display the information from the model like title, objective, etc. I'm also new to using APIs to get this information, so I've been looking through various places online, but I just can't figure out how to fit in the code examples online with the code I have from the template from GitHub.
One of the places I've looked: https://reactjs.org/docs/faq-ajax.html
Below is Hero.js. This is routed to the home page and it's just what the template provider named it. The code example provided above and in many other places I've looked puts all their code in App.js. I know they're just doing that for demonstration purposes, but I'm not sure how to fit it into the template code.
import React, { useState } from 'react';
import classNames from 'classnames';
import { SectionProps } from '../../utils/SectionProps';
import ButtonGroup from '../elements/ButtonGroup';
import Button from '../elements/Button';
import Image from '../elements/Image';
import { Link } from 'react-router-dom';
const propTypes = {
...SectionProps.types
}
const defaultProps = {
...SectionProps.defaults
}
const Hero = ({
className,
topOuterDivider,
bottomOuterDivider,
topDivider,
bottomDivider,
hasBgColor,
invertColor,
...props
}) => {
const outerClasses = classNames(
'hero section center-content',
topOuterDivider && 'has-top-divider',
bottomOuterDivider && 'has-bottom-divider',
hasBgColor && 'has-bg-color',
invertColor && 'invert-color',
className
);
const innerClasses = classNames(
'hero-inner section-inner',
topDivider && 'has-top-divider',
bottomDivider && 'has-bottom-divider'
);
return (
<section
{...props}
className={outerClasses}
>
<div className="container-sm">
<div className={innerClasses}>
<div className="hero-content">
<h1 className="mt-0 mb-16 reveal-from-bottom" data-reveal-delay="200">
BlueBird <span className="text-color-primary">Teaching</span>
</h1>
<div className="container-xs">
<p className="m-0 mb-32 reveal-from-bottom" data-reveal-delay="400">
An open source approach to education.
</p>
<div className="reveal-from-bottom" data-reveal-delay="600">
<ButtonGroup>
<Button tag="a" color="primary" wideMobile>
<Link to="/About">How This Works</Link>
</Button>
<Button tag="a" color="dark" wideMobile>
<Link to="/Test">Other Open Source Resources</Link>
</Button>
</ButtonGroup>
</div>
</div>
</div>
<div className="hero-figure reveal-from-bottom illustration-element-01" data-reveal-value="20px" data-reveal-delay="800">
<h2>Current Focus:</h2>
<h3 style={{ color: '#5b92e5' }}>(title)</h3>
<p style={{ textAlign: 'left', color: 'white' }}><strong>Objective: </strong>(Objective goes here)</p>
<p style={{ textAlign: 'left', color: 'white' }}>(Description goes here)</p>
<p style={{ textAlign: 'left', color: 'white', fontSize: 15 }}>The expected completion date of this focus is: (expected_completion_date)</p>
<h3>Preview</h3>
<Image style={{ padding: '30px' }}
src={require('./../../assets/images/Screenshot from 2020-08-03 07-52-33.png')}
alt="Hero"
width={896}
height={504} />
<Image
src={require('./../../assets/images/Screenshot from 2020-08-03 07-53-08.png')}
alt="Hero"
width={896}
height={504} />
</div>
</div>
</div>
</section>
);
}
Hero.propTypes = propTypes;
Hero.defaultProps = defaultProps;
export default Hero;
If needed, below is App.js.
import React, { useRef, useEffect } from 'react';
import { useLocation, Switch } from 'react-router-dom';
import AppRoute from './utils/AppRoute';
import ScrollReveal from './utils/ScrollReveal';
import ReactGA from 'react-ga';
// Layouts
import LayoutDefault from './layouts/LayoutDefault';
// Views
import Home from './views/Home';
import Test from './views/test';
import About from './views/About';
import Contact from './views/Contact';
// Initialize Google Analytics
ReactGA.initialize(process.env.REACT_APP_GA_CODE);
const trackPage = page => {
ReactGA.set({ page });
ReactGA.pageview(page);
};
const App = () => {
const childRef = useRef();
let location = useLocation();
useEffect(() => {
const page = location.pathname;
document.body.classList.add('is-loaded')
childRef.current.init();
trackPage(page);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location]);
return (
<ScrollReveal
ref={childRef}
children={() => (
<Switch>
<AppRoute exact path="/" component={Home} layout={LayoutDefault} />
<AppRoute exact path="/test" component={Test} layout={LayoutDefault} />
<AppRoute exact path="/about" component={About} layout={LayoutDefault} />
<AppRoute exact path="/contact" component={Contact} layout={LayoutDefault} />
</Switch>
)} />
);
}
export default App;
Thanks for any help and explanations!

So you just want to get your data from API and use it in your application.
Here is an little example for you with comments
import React, { useState, useEffect } from "react";
export default function Example() {
// Define our datas variable in state as an empty Array
const [datas, setDatas] = useState([]);
// useEffect will called after component will be rendered
useEffect(() => {
// Fetch our data from our API
fetch("https://jsonplaceholder.typicode.com/todos/")
// Resolve the responsove data
.then((response) => response.json())
.then((json) => {
// Show data in console
console.log(json)
// Set our API data to our datas array
setDatas([...json]);
});
}, []);
return (
<div>
<ul>
{/*
map is a build-in javascript function too loop through objects like foreach
So we just loop our array and render in our application
*/}
{datas.map((data, i) => (
<li key={i}> {data.title} </li>
))}
</ul>
</div>
);
}
I use javascript Fetch API function to get data from API but if you want, you can use something like Axios too.
If we want to use axios we just need to change useEffect like this for example;
First we need to install axios
npm install axios
Then, import or require axios
import axios from "axios";
// or
const axios = require('axios');
After these steps, just change useEffect function like this;
axios.get("https://jsonplaceholder.typicode.com/todos/")
.then(function (response) {
// handle success and show data in console
console.log(response.data);
// Set our API data to our datas array
setDatas([...response.data]);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
Javascript MAP: Array.prototype.map() - Mozilla Developers
Fetch API: Fetch API - Mozilla Developers
Axios: Axios Github Page
Axios vs Fetch API: Fetch vs. Axios.js for making http requests
Also I would suggest you to build your app from scratch rather than using a template to understand better and remember I just gave you a simple example, if you wanna build something for production you may want to build a different structure for your API requests.
I hope I could help, have a great day :)

Related

NextJS: what is the proper way to handle dynamic route pages?

I'm working on a project in NextJS for the first time, and I'm wondering what the right way to handle dynamic routing is.
I have a http://localhost:3000/trips route which displays a page with list of cards, each of which represent a "trip":
When I tap on one of these cards, I want to navigate to a dynamic page for that route such as http://localhost:3000/trips/0b68a50a-8377-4720-94b4-fabdabc12da1
This is my folder structure:
As you can see, I already have the dynamic routes set up and it is working.
TripCard is the card component. TripComponent is a grid of TripCards. trips/index.tsx contains the TripsComponent (and other UI).
Currently I'm handling the dynamic route in TripCard as:
import { Trip } from './Models'
import { useRouter } from 'next/router'
const TripCard = ({ trip }: { trip: Trip }) => {
const router = useRouter()
return (
<div className="card bg-base-100 shadow-xl hover:bg-gray-100 active:bg-gray-300">
<div className="card-body" onClick={() => router.push('/trips/' + trip.id)}>
<h2 className="card-title">{trip.name}</h2>
<p>This is a trip!</p>
</div>
</div>
)
}
export default TripCard
And the dynamic page [tripId].tsx looks like:
import { NextPage } from 'next'
import { useRouter } from 'next/router'
const TripPage: NextPage = () => {
const router = useRouter()
const tripId = router.query.tripId
return (
<div>
<h1>This is {tripId}</h1>
</div>
)
}
export default TripPage
And TripsComponent.tsx:
import { Trip } from './Models'
import TripCard from './TripCard'
const TripsComponent = ({ trips }: { trips: Trip[] }) => {
return (
<div>
<div className="grid grid-cols-4 gap-4">
{trips.map((trip: Trip) => (
<div>
<TripCard trip={trip}></TripCard>
</div>
))}
</div>
</div>
)
}
export default TripsComponent
And trips/index.tsx:
import axios from 'axios'
import { GetStaticProps, InferGetStaticPropsType, NextPage } from 'next'
import { Trip } from '../../components/Models'
import TripsComponent from '../../components/TripsComponent'
const TripsPage: NextPage = (props: InferGetStaticPropsType<typeof getStaticProps>) => {
return (
<div className="m-9">
<h1 className="mt-9 text-3xl font-bold text-slate-800">Your Trips</h1>
<div className="justify-end">
<button className="btn btn-primary">Add Trip</button>
</div>
<div className="divider"></div>
<TripsComponent trips={props.data} />
</div>
)
}
export const getStaticProps: GetStaticProps = async () => {
// fetches data and passes to props
}
export default TripsPage
I guess my question is, what is the proper way to do routing like this where I have cards, and each card will go to a dynamic URL with an associated page? In TripCard I have a hardcoded router.push:
<div className="card-body" onClick={() => router.push('/trips/' + trip.id)}>
But that doesn't seem like the right way to handle this. For example, what if I want to use TripCard in another view and go to another route?
What's the best way to structure code that performs this function in NextJS?
Maybe you want to pass the url as props and use NextJs <Link/>:
import { Trip } from './Models'
import { useRouter } from 'next/router'
import Link from 'next/link'
const TripCard = ({ trip, url }: { trip: Trip, url: string }) => {
const router = useRouter()
return (
<div className="card bg-base-100 shadow-xl hover:bg-gray-100 active:bg-gray-300">
<Link href={url} passHref>
<div className="card-body">
<h2 className="card-title">{trip.name}</h2>
<p>This is a trip!</p>
</div>
</Link>
</div>
)
}
export default TripCard
And then use the component like this:
<TripCard trip={trip} href={'/trips/' + trip.id}></TripCard>
Hope this help.
For dynamic routes, you will have to use getStaticPaths and getStaticProps to fetch the paths before and generate all the paths. When you export getStaticPaths from the page Nextjs will pre-render all the paths specified by getStaticPaths.
getStaicPaths has to return two things paths and fallback. paths property will have to be an array of params. And fallback means should Nextjs look for pages and pre-render if not pre-rendered before. Suppose after publishing the site you created a new card. So, If the fallback is true NextJs will look for the card in the database and pre-render then store it in the file system. If fallback is false it will show 404 not found.
Also Instead of using router.push use Link component.
https://nextjs.org/docs/api-reference/data-fetching/get-static-paths
The routing you have implemented is correct only. Maybe you can try like this
For trips, you can navigate to /trips and for each trip /trip/<trip id>
If you want to make the trip URL dynamic then you can pass the URL itself to TripCard component.
url will be <route name>/<trip id>
<TripCard trip={trip} url={url}></TripCard>

react/no-multi-comp is showing up as warnings

I am using hook router 1.2.5 and I have a very simple home page as below:
import { useRoutes } from "hookrouter";
import React from "react";
import Nav from "./pages/Nav";
import AboutPage from "./pages/About";
const HomePage = () => {
const routeResult = useRoutes({
"/about": () => <AboutPage />
});
return (
<div fluid>
<div xs={3} md={1} lg={1} className="nav-container">
<Nav />
</div>
<div xs={9} md={11} lg={11}>
{routeResult || <AboutPage />}
</div>
</div>
);
};
export default HomePage;
But when I run lint, I see below warnings show up.
8:10 warning Component definition is missing display name react/display-name
8:10 warning Declare only one React component per file react/no-multi-comp
I know I can disable these eslint warnings. But I would like to know how to fix them. For example, I don't have another component in my file. So why would it show react/no-multi-comp warning, or did I miss something? Any helps are appreciated.
UPDATE
I was able to fix react/display-name by replacing the arrow function as below:
const routeResult = useRoutes({
"/about"() {
return <AboutPage />;
}
});

Reactjs, Passing data(id) from one component to another in order to download a song

Hi I am new to Reactjs and I'm practicing on a project of a music website. But there is an issue which I'm stuck with.
Well there is a song page where I should show some songCards.
import React from 'react'
import SongCard from '../components/SongCard';
import { songsList } from '../components/songsList';
//this is first object of the songsList file which i hard coded instead of using api:
export const songsList =[
{
id : 1,
url : './components/Player/Songs/Homayoun Shajarian - Souvashoun.mp3',
image : require('../assets/Souvashoun.jfif').default,
name : 'x',
singer : 'y',
style :'z',
lyrics :'v',
source : './Palyer/Songs/Homayoun Shajarian - Souvashoun.mp3'
}];
export default function Songs() {
return(
<div>
<SongCard className='col-md-6' id={songsList[0].id} image={songsList[0].image} name={songsList[0].name} singer={songsList[0].singer}/><br/>
<SongCard className='col-md-6' id={songsList[1].id} image={songsList[1].image} name={songsList[1].name} singer={songsList[1].singer}/><br/>
<SongCard className='col-md-6' id={songsList[2].id} image={songsList[2].image} name={songsList[2].name} singer={songsList[2].singer}/><br/>
</div>
);
}
and in the SongCard which I'll attach the code bellow, there is a button intended to route us to a downloadMusic page in order to download the specific song that it's button was clicked:
import React from 'react'
import {Card, Button} from 'react-bootstrap';
import styled from 'styled-components';
import {BrowserRouter as Router} from 'react-router-dom';
function SongCard(props){
const id = this.props.id;
this.props.history.push({
pathname: '/downloadMusic',
search: '?query=downloadMusic',
state: { data: id }
})
return(
<Styles>
<Router>
<Card style={{ width: '18rem'}} className="cardbg shadow" text="white">
<Card.Img variant="top" src={props.image} className="img-fluid" />
<Card.Body className="text-center">
<Card.Title>آهنگ {props.name}</Card.Title>
<Card.Text>خواننده {props.singer}
</Card.Text>
<Button href="/DownloadMusic/:id" className="btn btn-outline-dark">go to download page</Button>
</Card.Body>
</Card>
</Router>
</Styles>
);
}
export default SongCard;
And finally this is the last page which is downloadMusic. Here also there should be a card containing information about the specific song and the final download button.
import React from 'react';
import { songsList } from './songsList';
import DownloadCard from './DownloadCard';
import AudioPlayer from './Player/AudioPlayer';
function DownloadMusic() {
const id = this.props.location.state.data;
const song = songsList.find(item => item.id === id);
return(
<div>
<DownloadCard className='col-md-6' id= {song.id} image={song.image} name={song.name} singer={song.singer}/><br/>
<AudioPlayer/>
</div>
);
}
export default DownloadMusic;
What I want is to send the id and url of that specific song that was clicked in the Song page, to downloadMusic page and show it's information from songsList in a card. I've tried so many ways like using state, useParams(), ... but none of them worked for me. Also I don't want to send the whole props because I know it's not the best practice. So what am I doing wrong?
Hope I've shared enough information. any help is appreciated.
what you have to do is map the array of songs, like this
import React from 'react'
import React from 'react'
import SongCard from '../components/SongCard';
import { songsList } from '../components/songsList';
//this is first object of the songsList file which i hard coded instead of using api:
const songsList =[
{
id : 1,
url : './components/Player/Songs/Homayoun Shajarian - Souvashoun.mp3',
image : require('../assets/Souvashoun.jfif').default,
name : 'x',
singer : 'y',
style :'z',
lyrics :'v',
source : './Palyer/Songs/Homayoun Shajarian - Souvashoun.mp3'
}];
export default function Songs() {
return(
<div>
{
songsList.map((song, idx) => {
return <SongCard key={idx} className='col-md-6' id={song.id} image={song.image} name={song.name} singer={song.singer}/>
})
}
</div>
);
}
Alright I finally found a way to do this, after a long effort! I'm gonna share it here if someone needed.
So in the SongCard.js I used useHistory() and a navigate function to save the id and navigate to downloadMusic page also in the onClick attribute of button used navigate function:
import React from 'react'
import {Card, Button} from 'react-bootstrap';
import styled from 'styled-components';
import {BrowserRouter as Router, useHistory} from 'react-router-dom';
function SongCard(props){
//navigating and saving id
const history = useHistory()
const navigate = (id) => {
history.push(`/downloadMusic/${id}`)
}
return(
<Styles>
<Router>
<Card style={{ width: '18rem'}} className="cardbg shadow" text="white">
<Card.Img variant="top" src={props.image} className="img-fluid" />
<Card.Body className="text-center">
<Card.Title>آهنگ {props.name}</Card.Title>
<Card.Text>خواننده {props.singer}
</Card.Text>
//make sure you add onClick attribute!
<Button onClick={() => navigate(props.id)} className="btn btn-outline-dark">download</Button>
</Card.Body>
</Card>
</Router>
</Styles>
);
}
export default SongCard;
Then in the DownloadMusic.js by using useRouteMatch() I accessed id param, this id was string so I converted it to number in the next step. At the end by using .find() method I found the specific song that was clicked for!
import React from 'react';
import { songsList } from './songsList';
import DownloadCard from './DownloadCard';
import AudioPlayer from './Player/AudioPlayer';
import { useRouteMatch } from "react-router-dom";
function DownloadMusic() {
//getting id param
const {
params: { id },
} = useRouteMatch('/downloadMusic/:id');
//converting the string id to number:
const num = Number(id);
//finding the song with song.id= num
const song = songsList.find(item => item.id === num);
return(
<div>
<DownloadCard className='col-md-6'
id= {song.id}
url= {song.url}
image={song.image}
name={song.name}
singer={song.singer}
/><br/>
<AudioPlayer id = {song.id}/>
</div>
);
}
export default DownloadMusic;
Just be careful about type of id, it must be number. this little one took me a long time.
:) Good luck!
You can create a function like this in the song card page
const onSongCardClick = () => {
history.push({
pathname: '/downloadMusic',
state: {id: this.props.id, url: this.props.url}
})
}
...
...
<Button onclick="onSongCardClick()" className="btn btn-outline-dark">go to download page</Button>
And get those values in Download music page by
const { id, url } = this.props.location.state
Also pass url as props to song card from songs page

react-admin edit component does not call update function

I'm working on a react-admin application and having an issue where the update function in my dataProvider is not called when the 'Save' button is clicked under the edit view.
My App.js looks like this:
import React, { useEffect } from 'react';
import { Switch, Route, Redirect, useLocation } from 'react-router-dom';
import { setGlobal, getGlobal } from 'reactn';
import ReactGA from 'react-ga';
import PrivateRoute from './Auth/PrivateRoute';
import UserLayout from './components/user/layout/Layout';
import AuthLayout from './components/auth/Layout';
import defaultGlobalState from './defaultGlobalState';
import portalApiDataProvider from "./providers/portalApiDataProvider";
import {Admin, ListGuesser, EditGuesser, ShowGuesser, Resource, Layout} from "react-admin";
import { UserList, UserEdit, UserShow } from '../src/components/admin/users';
import { AccountList } from "./components/admin/serviceAccounts";
import authProvider from "./providers/authProvider";
ReactGA.initialize(process.env.REACT_APP_GA_KEY);
const jwt = JSON.parse(localStorage.getItem('jwt'));
setGlobal({ ...defaultGlobalState, jwt });
const App = () => {
const { userId } = getGlobal();
let location = useLocation();
useEffect(() => {
ReactGA.pageview(location.pathname + location.search);
}, [location]);
return (
<Admin dataProvider={portalApiDataProvider} authProvider={authProvider}>
<Resource name="users" options={{label: 'Customer Profiles'}} list={UserList} show={UserShow} edit={UserEdit}/>
<Resource name="serviceAccounts" list={AccountList}/>
</Admin>
);
};
export default App;
My UserEdit is as follows:
<Edit title={<UserTitle/>} {...props}>
<SimpleForm>
<TextInput source="first_name" />
<TextInput source="last_name" />
<TextInput source="email" />
<TextInput source="phone" />
<TextInput source="default_account_number" />
<BooleanInput source="validated" format={v => v === 1 ? true : false}/>
</SimpleForm>
</Edit>
I've seen this issue brought up a couple of times, but without any details on resolution. This link mentions using a Notification component in the Layout (I'm pretty sure I'm using the default layout), or disabling undo (which does work but is not ideal): https://github.com/marmelab/react-admin/issues/3049
This link also discusses a similar issue with reference to a demo project, but I'm not able to find the relevant code: https://github.com/marmelab/react-admin/issues/5082
What am I missing here?
For some reason, the undoable prop on Edit is causing problem. Set it to false and it will call the update properly. I don't know why, I am using this under a special endpoint as a "sub-app", so might be due to conflicting routers, too tired to find out.
You should set the mutationMode of Edit into "pessimistic"
So your will be
<Edit
{...props}
mutationMode="pessimistic"
>
Document here: https://marmelab.com/react-admin/CreateEdit.html#mutationmode

Importing FontAwesome icons by string array in React.js

I'm having an array of sidebar elements in my React.js project where each element is represented as object which among others has its own FontAwesome icon defined as string, like e.g. fa-phone. Now there's a problem with FontAwesome's integration into React.js; each icon has to be separately imported and added to the library, according to their manual.
import * as React from 'react';
import { library } from '#fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
interface SidebarElement {
fa: string,
href: string,
title: string
}
interface SidebarElements {
elements: SidebarElement[]
}
export default class Sidebar extends React.Component<SidebarElements, {}> {
render() {
const elements = this.props.elements.map((element, key) => {
// tweak icon name so it matches component name...?
...
// the two lines below obviously won't work
import { element.fa } from '#fortawesome/free-solid-svg-icons'
library.add(element.fa);
return (
<li key={key} className="nav-item">
<a className="nav-link" href={element.href}>
<FontAwesomeIcon icon={element.fa} />
<span>{element.title}</span>
</a>
</li>
);
})
return (
<ul className="sidebar navbar-nav">{elements}</ul>
);
}
}
But the solution above obviously won't work, since imports have to happen at top-level and won't take the component name from a variable. Are there any alternative ways to import icons without exactly knowing them from the beginning? Or am I forced to import all icons at the same point I'm defining my sidebar elements?
I went with this same issue on a personal project I'm building. The first problem I found was related to how dynamically rendering the icon from a query?
Main app container:
import React from "react"
import Header from "../components/header"
import Navigation from "../components/navigation"
import Footer from "../components/footer"
import containerStyles from "./styles.module.less"
import { library } from "#fortawesome/fontawesome-svg-core"
import { fab } from "#fortawesome/free-brands-svg-icons"
library.add(fab)
const IndexPage = ({ data }) => (
<div className={containerStyles.home}>
<div className={containerStyles.menu}>
<Header />
<Navigation />
</div>
<Footer />
</div>
)
export default IndexPage
Also, my icons are part of the free-brand version so imported them to the library.
So the first thing I did was to import the library and create a pair of null variables on my child component, one for the prefix and the other one for the icon itself:
In my project, I'm consuming the data from an API endpoint, the query I built to get the information is the following:
Theoretically, all was set just for mapping the array and render each item as we normally do:
<FontAwesomeIcon
icon={[
(faprefix = document.node.prefix),
(faicon = document.node.icon),
]}
size="lg"
/>
But the child component was rendering nothing. Why was this? Simply because of both document.node.prefix and document.node.icon are returning strings so when the component mapped the data from the array, it ended trying to render something like this:
<svg data-prefix="'fab'" data-icon="'github'" >
Please note the single quotation mark wrapping the string
My solution to this was to use a replace() method with a regex to remove the wrapping quotations marks:
<FontAwesomeIcon
icon={[
(faprefix = document.node.prefix.replace(/'/g, "")),
(faicon = document.node.icon.replace(/'/g, "")),
]}
size="lg"
/>
Child footer component
import React from "react"
import { StaticQuery, graphql } from "gatsby"
import containerStyles from "../pages/styles.module.less"
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome"
let faicon = null
let faprefix = null
const Navigation = ({ data }) => (
<StaticQuery
query={graphql`
query FooterTemplate {
allStrapiLink {
edges {
node {
id
icon
url
prefix
}
}
}
}
`}
render={data => (
<>
<footer>
<p>Freddy Polanía {new Date().getFullYear()}</p>
<div className={containerStyles.links}>
{data.allStrapiLink.edges.map(document => (
<div key={document.node.id}>
<a
href={document.node.url}
rel="noopener noreferrer"
target="_blank"
>
<FontAwesomeIcon
icon={[
(faprefix = document.node.prefix.replace(/'/g, "")),
(faicon = document.node.icon.replace(/'/g, "")),
]}
size="lg"
/>
</a>
</div>
))}
</div>
</footer>
</>
)}
/>
)
export default Navigation
Now my icons are rendering from the endpoint's data. I hope this could help to solve your issue.

Categories

Resources