I'm using react to create a web-app that has to be static so no API calls and I need to store some data client-side (I'm currently just using a single JSON file as it's really not large) but I'm struggling to pass images down, I'm storing the references as strings in the JSON file and passing them to the props but I'm getting all sorts of errors. Is there a better or more practical way to do this?
Code (I've added a variable to imitate the JSON structure):
const HomePage = () => {
let projectInfo: ProjectInfo = {
title: "Project",
description:
"A progressive web app.",
imgURL: "./TODO", //<- HERE
mainColour: "#323232",
secondaryColour: "#464646",
};
return (
<div id="carousel-container">
<Carousel labels={["1"]}>
<ProjectPanel info={projectInfo} />
</Carousel>
</div>
);
};
export default HomePage;
interface IProjectPanelProps {
info: ProjectInfo;
}
const ProjectPanel = (props: IProjectPanelProps) => {
return (
<div className="project-panel">
<h2>{props.info.title}</h2>
<p>{props.info.description}</p>
<img src={/* ?? */} alt=""></img>
</div>
);
};
You can use base64 images to store them.
See this post https://stackoverflow.com/a/42399865/1356340 for examples of how to use binary images in React.
You can import your image in your home page as a variable and pass that variable to your child component.
import myImage from 'your_image_path';
const HomePage = () => {
let projectInfo: ProjectInfo = {
title: "Project",
description:
"A progressive web app.",
imgURL: myImage
mainColour: "#323232",
secondaryColour: "#464646",
};
return (
<div id="carousel-container">
<Carousel labels={["1"]}>
<ProjectPanel info={projectInfo} />
</Carousel>
</div>
);
};
export default HomePage;
interface IProjectPanelProps {
info: ProjectInfo;
}
const ProjectPanel = (props: IProjectPanelProps) => {
return (
<div className="project-panel">
<h2>{props.info.title}</h2>
<p>{props.info.description}</p>
<img src={info.imgURL} alt=""></img>
</div>
);
};
Related
I want to consume restful api in react application via bootstrap. But I can't mapping correctly. I believe that the problem is brackets. But I couldn't figure out. (ignore my div part if I can mapping, I will update that part.)
My restful api: https://api.coindesk.com/v1/bpi/currentprice.json
Restful api Json formatted:
{
"time":{
"updated":"Jun 2, 2022 08:38:00 UTC",
"updatedISO":"2022-06-02T08:38:00+00:00",
"updateduk":"Jun 2, 2022 at 09:38 BST"
},
"disclaimer":"This data was produced from the CoinDesk Bitcoin Price Index (USD). Non-USD currency data converted using hourly conversion rate from openexchangerates.org",
"chartName":"Bitcoin",
"bpi":{
"USD":{
"code":"USD",
"symbol":"$",
"rate":"29,941.3155",
"description":"United States Dollar",
"rate_float":29941.3155
},
"GBP":{
"code":"GBP",
"symbol":"£",
"rate":"23,980.6882",
"description":"British Pound Sterling",
"rate_float":23980.6882
},
"EUR":{
"code":"EUR",
"symbol":"€",
"rate":"28,094.2357",
"description":"Euro",
"rate_float":28094.2357
}
}
}
My App.js
import React, {Component} from 'react';
import Lists from './example/lists';
class App extends Component {
render() {
return (
<Lists lists={this.state.lists} />
)
}
state = {
lists: {}
};
componentDidMount() {
fetch('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(res => res.json())
.then((data) => {
this.setState({ lists: data })
})
.catch(console.log)
}
}
export default App;
My list.js:
import React from 'react'
const Lists = ({lists}) => {
return (
<div>
<center><h1>Exchange</h1></center>
{lists.map((list) => (
<div class="card">
<div class="card-body">
<h5 class="card-title">{list.time}</h5>
<h5 class="card-title">{list.bpi}</h5>
</div>
</div>
))}
</div>
)
};
export default Lists
The json is not an array therefore no you do not need to map through it. Remove the map from the List component.
import React from 'react'
const Lists = ({lists}) => {
return (
<div>
<center><h1>Exchange</h1></center>
<div class="card">
<div class="card-body">
<h5 class="card-title">{lists.time}</h5>
<h5 class="card-title">{lists.bpi}</h5>
</div>
</div>
</div>
)
};
export default Lists
I am not sure your json is complete but, since your json is returning an object, you cannot use map or any loop. You just need to display the data without looping
I'm moving my blog from Jekyll to NextJS and missing a feature to return all posts in one list.
From the official examples and other sources, I see that posts are written in markdown, and developers need to read a directory with posts, parse files, extract front matter, etc.
But I heavily use schema.org attributes, and all posts are written in pure HTML, I only replaced img elements with NextJS implementation.
So instead of using frontmatter, I renamed my posts' file extension to .js and rewrote its contents to this:
import Breadcrumbs from '/components/breadcrumbs';
import PostHeader from '/components/postheader';
export async function getStaticProps() {
return {
props: {
title: "How to start investing",
description: "How to start investing in 2022",
published: "2021-08-01",
modified: "2022-04-09",
tags: ["investing", "how-to"]
}
}
}
export default function Post() {
return <>
<Breadcrumbs />
<article itemscope itemtype="https://schema.org/TechArticle">
<PostHeader />
<div>
blah.. blah.. blah..
</div>
</article>
</>
}
So is there a way to get Component props by given folder path or something like that without parsing files?
import PropTypes from 'prop-types';
export default function Post(props) {
return <>
<Breadcrumbs />
<article itemscope itemtype="https://schema.org/TechArticle">
<PostHeader />
<div>
<p>{props.title}</p>
<p>{props.description}</p>
<p>{props.published}</p>
<p>{props.modified}</p>
<p>{props.tags}</p>
</div>
</article>
</>
}
ComponentName.prototype ={
title: String,
description:string,
published: VarDate,
modified: VarDate,
tags:String
}
I ended up storing all posts in a simple javascript list
export default ([
{
title: "How to start investing",
description: "How to start investing in 2022",
published: "2021-08-01",
modified: "2022-10-23",
tags: ["investing", "how-to"],
slug: "how-to-start-investing",
img: "startinvesting",
excerpt: `
Post excertp text...
`
},
{...}
])
and then importing it in GetStaticProps, filtering by post slug
import Image from 'next/image'
import posts from '../../../data/posts'
import Breadcrumbs from '../../../components/breadcrumbs'
import PostHeader from '../../../components/post-header'
export async function getStaticProps() {
return {
props: {
...posts.find(post => post.slug == 'how-to-start-investing')
}
}
}
export default function Post(props) {
return <>
<h1>{props.title}</h1>
Post text...
</>
}
I am making a simple website and I would like to fetch data from an API and display it on my component.
The problem is that the getStaticProps() method is never called.
Here is the code of the component :
import React from "react";
import {GetStaticProps, InferGetStaticPropsType} from "next";
type RawProject = {
owner: string;
repo: string;
link: string;
description: string;
language: string;
stars: number;
forks: number;
}
function Projects({projects}: InferGetStaticPropsType<typeof getStaticProps>) {
console.log(projects);
return (
<section id="projects" className="bg-white p-6 lg:p-20">
<h1 className="sm:text-4xl text-2xl font-medium title-font mb-4 text-gray-900 pb-6 text-center">
Quelques de mes projets
</h1>
{/*
<div className="container px-5 mx-auto">
<div className="flex flex-wrap">
{rawProjects.map((project: RawProject) => (
<ProjectCard
title={project.repo}
language={project.language}
description={project.description}
imageUrl="https://dummyimage.com/720x400"
repoUrl={project.link}
/>
))}
</div>
</div>
*/}
</section>
);
}
export const getStaticProps: GetStaticProps = async () => {
console.log("getStaticProps()");
const res = await fetch("https://gh-pinned-repos-5l2i19um3.vercel.app/?username=ythepaut");
const projects: RawProject[] = await res.json();
return !projects ? {notFound: true} : {
props: {projects: projects},
revalidate: 3600
};
}
export default Projects;
The full code can be found here : https://github.com/ythepaut/webpage/tree/project-section
I am not sure if the problem is caused by the fact that I use typescript, or that I use a custom _app.tsx
I tried the solutions from :
https://github.com/vercel/next.js/issues/11328
How to make Next.js getStaticProps work with typescript
but I couldn't make it work.
Could someone help me please ?
Thanks in advance.
getStaticProps() is only allowed in pages.
Your code at the moment is :
import Hero from "../sections/Hero";
import Contact from "../sections/Contact";
import Projects from "../sections/Projects"; // you cannot call getStaticProps() in this componenet
function HomePage(): JSX.Element {
return (
<div className="bg-gray-50">
<Hero />
<Projects />
<Contact />
</div>
);
}
export default HomePage;
Instead call getStaticProps() inside index.tsx and pass the props to the component something like this ::
import Hero from "../sections/Hero";
import Contact from "../sections/Contact";
import Projects from "../sections/Projects";
function HomePage({data}): JSX.Element {
return (
<div className="bg-gray-50">
<Hero />
<Projects data={data} />
<Contact />
</div>
);
}
export const getStaticProps: GetStaticProps = async () => {
console.log("getStaticProps()");
const res = await fetch("https://gh-pinned-repos-5l2i19um3.vercel.app/?username=ythepaut");
const projects: RawProject[] = await res.json();
return !projects ? {notFound: true} : {
props: {projects: projects},
revalidate: 3600
};
}
export default HomePage;
Data fetching methods in NextJs like getStaticProps runs only on the server. Hence it works only in pages, not in a regular react component
Please Check their docs
For data fetching in Normal Components, You can only do client-side Rendering. NextJS recommends using this library SWR
According to their docs
SWR is a strategy to first return the data from cache (stale), then send the fetch request (revalidate), and finally, come with the up-to-date data.
You can only use getInitialProps, getServerSideProps, getStaticProps in Next.js pages
I checked your project and saw that your Project.tsx was in a component folder, but it needs to be in pages folder for those functions to work.
I got a similar bad experience because of bad service worker implementation, if you found it works with "Empty Cache and Hard Reload", you should check your service-worker code, you may don't want to cache any pages.
In pages folder you must export getStaticProps too
Example
export { default } from '../../games/tebak-kata/game';
export { getStaticPaths } from '../../games/tebak-kata/game';
export { getStaticProps } from '../../games/tebak-kata/game';
I want to pass props from one component to another, and use it in the second one for an import above the component declaration
This is for using the same component, with no need to create it 4 times, every time with another SVG.
I'm using React, Javascript, Webpack, babel.
I'm also using svgr/webpack to create a component from an SVG picture, and it's crucial for me to use SVG not < img >.
import React from 'react';
import RightNavItem from './right_nav_item';
const RightNav = ({navitems}) => {
const rightNavItems = navitems.map( (item) => {
return <RightNavItem name={ item }/>
});
return(
<div className="rightnav">
{rightNavItems}
</div>
);
};
.
export default RightNav;
import React from 'react';
const RightNavItem = ({ name }) => {
const svgpath = `../../../../resources/img/navbar/${name}.svg`;
return(
<div>
<img src={ svgpath } style={{height: '25px'}}/>
<span>{ name }</span>
</div>
);
};
export default RightNavItem;
And I want to achieve being able to do this:
import React from 'react';
import SvgPicture from '../../../../resources/img/navbar/{name}.svg';
const RightNavItem = ({ name }) => {
return(
<div>
<SvgPicture />
<span>{ name }</span>
</div>
);
};
export default RightNavItem;
.
Ok so I went back and implemented the whole thing on my local app to get exactly what you need. I am editing my original answer. Hope this solves your issue.
The parent:
import React from 'react';
import { ReactComponent as svg } from 'assets/img/free_sample.svg';
import RightNavItem from './RightNavItem';
const LOGOS = [
{ name: 'home', svg },
{ name: 'home', svg },
];
const RightNav = () => (
<div>
{LOGOS.map(logo => (
<RightNavItem name={logo.name}>
<logo.svg />
</RightNavItem>
))}
</div>
);
export default RightNav;
The child:
import React from 'react';
const RightNavItem = ({ name, children }) => (
<div>
{children}
<span>{name}</span>
</div>
);
export default RightNavItem;
You don't need to import the svg as I did, if you are able to use svg as a component in your webpack config then continue to do what you were doing before.
I managed to do it in a kind of ugly way, but it works.
The problem is if I have more than 4 items, then using it without the map() function can be really annoying.
I used {props.children}, and instead of using map(), I added the 4 times, each with different 'SVG' component child and different props 'name', that way the component only gets initialized at the RightNavItem level.
IF SOMEONE KNOWS how can I use this with the map() function, It'll help a lot!
Thanks to everyone who helped!
For example:
const RightNav = (props) => {
return(
<div className = "rightnav">
<RightNavItem name = {home}>
<HomeSVG />
</RightNavItem>
<RightNavItem name = {profile}>
<ProfileSVG />
</RightNavItem>
.
.
.
</div>
);
};
And in the RightNavItem:
const RightNavItem = (props) => {
return(
<div>
{props.children}
<span>{ props.name }</span>
</div>
);
};
I have problem with displaying pagination. I'm using Wordpress REST API to fetch my posts
Here is my code:
import React, { Component } from "react";
import "./App.css";
class App extends React.Component {
constructor() {
super();
this.state = {
items: [],
totalPages: '',
nextPage: '',
};
this._loadData = this._loadData.bind(this);
}
componentDidMount() {
const url = 'http://localhost/wp-json/wp/v2/';
this._loadData(url);
}
_loadData(url) {
request.get(url).then((response) => {
this.setState({
items: response.body.items.data,
totalPages: response.body.items.last_page,
nextPage: response.body.items.next_page_url
});
});
}
render() {
let items = _.map(this.state.items, (item) => {
return (
<div key={item.id}>
<div className="content">
<span>
{item.type}
</span>
</div>
</div>
)
});
return (
<div>
{items}
</div>
<div>
<a href="#0" onClick={this._loadData(this.state.nextPage)}/>Next
</div>
}
}
export default App;
I need help beacuse I can not figure out where the problem is. I would appreciate some tutorial or something like that.
Your WordPress's REST API Endpoint isn't correct.
When you fetching data from http://localhost/wp-json/wp/v2/ using GET method, it will returns only the namespaces and routes.
If you would like to pull posts or pages, should use path like this.
http://localhost/wp-json/wp/v2/{post_type}
Replace {post_type} with the post type in plural word.
For example you would like to get latest posts you should request to
http://localhost/wp-json/wp/v2/posts
Also you can preview this url in your browser.