Show post content in the same page ReactJS - javascript

i'm creating a blog. in my index.js i have a left sidebar that shows the article links.
What I'm trying to do is when I click on the link the post content should be shown in the right sidebar of my index.js
At the moment it's been opened in a new page.
index.js
const IndexPage = ({
data: {
allMarkdownRemark: { edges },
},
}) => {
const PostData = edges[0]
const Posts = edges
.filter(edge => !!edge.node.frontmatter.date) // You can filter your posts based on some criteria
.map(edge => <PostLink key={edge.node.id} post={edge.node} />)
return (
<div className='html-container'>
<div className='main-container'>
<div className='row'>
<div className='left-sidebar'>
<div className='logo'>
<p>logo</p>
</div>
<div className='menu'>
{Posts}
</div>
<div className='social'>
<img src={twitch} />
<img src={discord} />
<img src={twitter} />
<img src={email} />
</div>
</div>
<div className='right-sidebar'>
</div>
</div>
</div>
</div>
)
}
post-link.js
import React from "react"
import { Link } from "gatsby"
const PostLink = ({ post }) => (
<div>
<Link to={"/blog"+post.frontmatter.slug}>
{post.frontmatter.title}
{/* {post.frontmatter.title} ({post.frontmatter.date}) */}
</Link>
</div>
)
export default PostLink

Check the API of the Link and if it has an equivalent of target attribute.

Related

my react.js app is coming blank trying to seed with an external js file

I just started studying react, so I picked up the book Fullstack react by Anthony Accomozzio et al, with the latest version on January 13, 2020. I created the react app with npx create-react-app I am stuck on the part of 'making product data driven', I'm trying to seed data from an external file seed.js using props, but it returns a blank screen. But runs if data is hard encoded.
App.js:
import logo from './logo.svg';
import './App.css';
import './seed';
function App() {
const product = window.Seed.products[1];
return (
<div className="App">
<Product
id = {product.id}
title = {product.title}
decription = {product.description}
url = {product.url}
votes = {product.votes}
submitterAvatarUrl = {product.submitterAvatarUrl}
productImageUrl = {product.productImageUrl}
/>
</div>
);
}
const Product = () => {
return (
<div className = 'item'>
<div className = 'image'>
<img src = {this.props.productImageUrl} />
</div>
<div className = 'middle aligned content'>
<div className = 'header'>
<a>
<i className = 'large caret up icon' />
</a>
{this.props.votes}
</div>
<div className = 'description'>
<a href = {this.props.url}>
{this.props.title}
</a>
<p>
{this.props.description}
</p>
</div>
<div className='extra'>
<span>Submitted by:</span>
<img
className='ui avatar image'
src = {this.props.submitterAvatarUrl}
/>
</div>
</div>
</div>
);
}
export default App;
The seed.js that has the data:
window.Seed = (function (){
function generateVoteCount() {
return Math.floor((Math.random() * 50) + 15);
}
const products = [
{
id: 1,
title: 'Yellow Pail',
description: 'On-demand sand castle construction expertise.',
url: '#',
votes: generateVoteCount(),
submitterAvatarUrl: 'images/avatars/daniel.jpg',
productImageUrl: 'images/products/image-aqua.png',
},
...
];
return { products: products };
}());
Is the codes deprecated for the react version?
Your Product component is a functional component which means there is no this.props.
You'll need to take in the props as an argument and then you can use prop.xxx to access the values.
const Product = (props) => {
return (
<div className="item">
<div className="image">
<img src={props.productImageUrl} />
</div>
<div className="middle aligned content">
<div className="header">
<a>
<i className="large caret up icon" />
</a>
{props.votes}
</div>
<div className="description">
<a href={props.url}>{props.title}</a>
<p>{props.description}</p>
</div>
<div className="extra">
<span>Submitted by:</span>
<img className="ui avatar image" src={props.submitterAvatarUrl} />
</div>
</div>
</div>
);
};

Next js component doesn't show without reload

Basically, I have a nested component that I want to render with the parent component and it's working fine when the server starts.
But the problem arises when I switch back from another page. Some of the nested components get disappeared. If I made a refresh then again everything ok.
How can I solve this issue?
Normal:
Image-1
Component disappeared:
Image-2
Index.js:
import BannerBaseLine from "./../components/HOME/Banner/BannerBaseLine";
import SubSection1 from "./../components/ABOUT/subSection1";
import CoursesList from "../components/HOME/MOSTTRENDING/CoursesList/courseslist";
import ShortOverview from "./../components/HOME/CourseOverviewSection/Section1/shortoverview";
import Testimonial from "./../components/HOME/Testimonial/testimonial";
import ClientItem from "./../components/HOME/Client-area/all-client-item";
export default function HomeMain({categories}) {
return (
<>
<br></br>
<br></br>
<br></br>
<BannerBaseLine categories = {categories} />
<CoursesList />
{/* <SubSection1 /> */}
<ShortOverview />
<CoursesList />
<Testimonial />
<ClientItem />
</>
);
}
export async function getStaticProps(){
const response = await fetch('http://localhost:8000/api/data/categories')
const data = await response.json()
console.log(data)
return {
props:{
categories : data,
}
}
}
BannerBaseLine component:
import BannerBlock from './BannerBlock';
export default function BannerBaseLine({ categories }) {
return (
<>
<section
className="banner-area"
style={{ backgroundImage: "url(assets/img/banner/0.jpg)" }}
>
<div className="container">
<div className="row">
<div className="col-lg-6 col-md-8 align-self-center">
<div className="banner-inner text-md-start text-center">
<h1>
Find the Best <span>Courses</span> & Upgrade{" "}
<span>Your Skills.</span>
</h1>
<div className="banner-content">
<p>
Edufie offers professional training classes and special
features to help you improve your skills.
</p>
</div>
<div className="single-input-wrap">
<input type="text" placeholder="Search your best courses" />
<button>
<i className="fa fa-search"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</section>
<br></br>
<br></br>
<div className="container">
<div className="intro-area-2">
<div className="row justify-content-center">
<div className="col-lg-12">
<div className="intro-slider owl-carousel">
{categories.map((category) => {
return (
<>
<BannerBlock category={category} key={category.id} />
</>
);
})}
</div>
</div>
</div>
</div>
</div>
</>
);
}
BannerBlock component:
export default function BannerBlock({category}) {
console.log(category);
return (
<div className="item">
<div className="single-intro-wrap">
<div className="thumb">
<img src={category.image} alt="img" />
</div>
<div className="wrap-details">
<h6>
{category.Base_Category_Title}
</h6>
<p>236 Course Available</p>
</div>
</div>
</div>
);
}
From https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation
Note: You should not use fetch() to call an API route in
getStaticProps. Instead, directly import the logic used inside your
API route. You may need to slightly refactor your code for this
approach.
Fetching from an external API is fine!
you should check if categories exist
export default function HomeMain({categories}) {
if(categories){
return <Loading Component />
}
rest of the code...
}

Redirecting to external link using ReactJS

I want to add button property which will redirect to external link when it is clicked. prop which should be added to button is siteURL .Button should be in class = "project-item-details-container". Do I have to install any external package?
sample button: Visit site
code which I have written -
const ProjectItem = props => {
const {projectDetails} = props
const {projectId, imageURL, description, title, siteURL} = projectDetails
return (
<>
<li className="project-item-container">
<img
className="project-item-image"
src={imageURL}
alt={`project-item${projectId}`}
/>
<div className="project-item-details-container">
<h1 className="project-item-title">{title}</h1>
<p className="project-item-description">{description}</p>
</div>
</li>
</>
)
}
const ProjectItem = props => {
const {projectDetails} = props
const {projectId, imageURL, description, title, siteURL} = projectDetails
return (
<>
<li className="project-item-container">
<img
className="project-item-image"
src={imageURL}
alt={`project-item${projectId}`}
/>
<div className="project-item-details-container">
<h1 className="project-item-title">{title}</h1>
<p className="project-item-description">{description}</p>
</div>
<a href={siteUrl}>{title}</a>
</li>
</>
)
}
you can do something like this
const ProjectItem = props => {
const {projectDetails} = props
const {projectId, imageURL, description, title, siteURL} = projectDetails
return (
<>
<li className="project-item-container">
<img
className="project-item-image"
src={imageURL}
alt={`project-item${projectId}`}
/>
<div className="project-item-details-container">
<h1 className="project-item-title">{title}</h1>
<p className="project-item-description">{description}</p>
<button onClick={()=>window.location.href=siteURL}>{title}</button>
</div>
</li>
</>
)
}
Well, I solved this.
I have used attribute in button element.
const ProjectItem = props => {
const {projectDetails} = props
const {projectId, imageURL, description, title, siteURL} = projectDetails
return (
<>
<li className="project-item-container">
<img
className="project-item-image"
src={imageURL}
alt={`project-item${projectId}`}
/>
<div className="project-item-details-container">
<h1 className="project-item-title">{title}</h1>
<p className="project-item-description">{description}</p>
<button type="button" className="project-redirect-button">
<a href={siteURL} alt="Broken Link">
Visit Site
</a>
</button>
</div>
</li>
</>
)
}

How to transfer image and data between components | React

In the project I have a Upload image component that asks the user for an image and then previews it on the page. The image is not persay "uploaded" to any server and I hope that it does'nt need to. The goal is to be able to compare this uploded image with a random active set of images from an API (Image.js). What I have problem with is how to use the previewImage: URL.createObjectURL(event.target.files[0]) inside of another file, or at least that is what I belive to be the right way to think about it. (For context: The idea is to check the correlation between the uploaded file and the random active set.)
I have tried to implement an child to child state transfer but gave up when it did not work for the child to parent part. App.js is the parent, Image.js and image-upload.component.js are the children. I have also looked for ways to solve this with redux but don't understand how to store images or utilize states inside of the store. For this i only need to update the image state when files are selected by user.
To somewhat summarize and clarify the question: How can I transfer the chosen image file between two components and use the data in both of them?
This is my first project in React so the code may be caotic and full of "brute force" so I apologice in advance for that. Any help or guidence is greatly appreciated!
App.js:
import React from "react";
import "./App.css";
import Navbar from './components/Navbar/Navbar'
import "bootstrap/dist/css/bootstrap.min.css";
import UploadImages from "./components/image-upload.component";
import Images from "./components/Images";
function App() {
return (
<div className="App">
<Navbar />
<div className="container">
<div className="row">
<div className="col-5">
<div className="content">
<h3>Title</h3>
<h4>Upload my picture here</h4>
<UploadImages/>
</div>
</div>
<div className="col-2">
</div>
<div className="col-5">
<Images />
</div>
</div>
</div>
</div>
);
}
export default App;
Images.js (pure, brute force code i guess):
import UploadImages from "./image-upload.component";
import React, {useEffect, useState} from "react";
import "./Images.css";
function shuffleArray(array) {
let i = array.length - 1;
for (; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
const temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
function Images() {
const [urls, setURLs] = useState([]);
const [count, setCount] =useState(0)
useEffect(() => {
const urls = [
250940,
20622,
436625,
436444,
436509,
359245,
459090,
333933,
333916,
466350,
44831,
383010,
202660,
406317,
337349,
503448,
12617,
248662,
435805,
438545
].map(
(itemId) =>
`https://collectionapi.metmuseum.org/public/collection/v1/objects/${itemId}`
);
shuffleArray(urls)
Promise.all(
urls.map((currUrl) =>
fetch(currUrl)
.then((response) => response.json())
.then((data) => data.primaryImage)
.catch((error) => console.log("There was a problem!", error))
)
).then((fetchedUrls) => setURLs(fetchedUrls));
}, []);
if (count === 3) {
return (
<div>
<div class="imageContainer">
<div class="images__item">
<img class="photo" src={urls[1]} alt="" />
</div>
<div class="images__item">
<img class="photo" src={urls[2]} alt="" />
</div>
<div class="images__item">
<img class="photo" src={urls[3]} alt="" />
</div>
</div>
<button
onClick={() => setCount(4)}>
Next
</button>
</div>
)
}
if (count === 4) {
return (
<div>
<div class="imageContainer">
<div class="images__item">
<img class="photo" src={urls[1]} alt="" />
</div>
<div class="images__item">
<img class="photo" src={urls[2]} alt="" />
</div>
<div class="images__item">
<img class="photo" src={urls[3]} alt="" />
</div>
<div class="images__item">
<img class="photo" src={urls[4]} alt="" />
</div>
</div>
<button
onClick={() => setCount(3)}>
Previous
</button>
<button
onClick={() => setCount(5)}>
Next
</button>
</div>
)
}
if (count === 5) {
return (
<div>
<div class="imageContainer">
<div class="images__item">
<img class="photo" src={urls[1]} alt="" />
</div>
<div class="images__item">
<img class="photo" src={urls[2]} alt="" />
</div>
<div class="images__item">
<img class="photo" src={urls[3]} alt="" />
</div>
<div class="images__item">
<img class="photo" src={urls[4]} alt="" />
</div>
<div class="images__item">
<img class="photo" src={urls[5]} alt="" />
</div>
</div>
<button
onClick={() => setCount(4)}>
Previous
</button>
<button
onClick={() => {setCount(3); shuffleArray(urls);}}>
Reset
</button>
</div>
)
}
else {
return (
<div>
{/* <UploadImages upsideEmit={getStateFromChild} /> */}
<button
onClick={() => {shuffleArray(urls); setCount(3);}}>
Open
</button>
</div>
);
}
}
export default Images;
image-upload.component.js:
import React, { Component } from "react";
import UploadService from "../services/file-upload.service";
import "./Images"
class UploadImages extends Component {
constructor(props) {
super(props);
this.selectFile = this.selectFile.bind(this);
this.upload = this.upload.bind(this);
this.state = {
currentFile: undefined,
previewImage: undefined,
progress: 0,
message: "",
imageInfos: [],
};
}
componentDidMount() {
UploadService.getFiles().then((response) => {
this.setState({
imageInfos: response.data,
});
});
}
selectFile(event) {
this.setState({
currentFile: event.target.files[0],
previewImage: URL.createObjectURL(event.target.files[0]),
message: ""
});
}
upload() {
this.setState({
progress: 0,
});
UploadService.upload(this.state.currentFile, (files) => {
this.setState({
imageInfos: files.data,
});
})
}
render() {
const {
previewImage,
} = this.state;
return (
<div>
<div className="row">
<div className="col-8">
<label className="btn btn-default p-0">
<input type="file" accept="image/*" onChange={this.selectFile} />
</label>
</div>
<div className="col-4">
</div>
</div>
{previewImage && (
<div>
<img className="preview" src={previewImage} alt="" />
</div>
)}
</div>
);
}
}
export default UploadImages
In general you would want to useContext hook for this.
Check out this tutorial https://dev.to/email2vimalraj/react-hooks-lift-up--pass-down-state-using-usecontext-and-usereducer-5ai0

Having trouble rendering an array of images from an api (Django Rest Framework) response in React

Hi this is my first project in both React and Django Rest Framework and I need to figure this out to complete the project.
The issue I'm having (I believe it's a React one) is that my api is returning an json response which React receives using axios which works fine since when I do the console log all the data is there and Im also able to pass the data to a tag, etc. I would like to display the photos that are being sent to by the api. The link is not the problem as I am able to view the photo in the browser using the link provided by the api. The problem is that I have multiple images in the api response that are set up as an array.
As shown here:
postmanResponse
Response using console:
enter image description here
I guess essentially what I'm asking is there a way that I can make an array/object with the image array that my api is delivering so that I can then use it to show the picture in React?
Any help will be helpful. Thank you!
Here is my code for the React side:
// Import Files
import React, { Component } from 'react';
// Import Axios
import axios from "axios";
// Import Is Mobile
import { isMobile } from 'react-device-detect';
// Import Css
import "./projectDetail.css";
// Mobile Css
import "./projectDetailM.css"
// Lightbox
import { SRLWrapper } from "simple-react-lightbox";
// Import Footer
import Footer from "../Footer/footer"
// Project Detail Class
class ProjectDetail extends Component {
// States
state = {
data: [],
photoIndex: 0,
isOpen: false,
}
// Mount Data to the State
componentDidMount() {
this.handleFetchItem();
}
// Get the project via axios
handleFetchItem = () => {
// Variables
const {
match: { params }
} = this.props
// Set State
this.setState({ loading: true });
// Axios Setup
axios.get('http://127.0.0.1:8000/projects/' + params.ID)
.then(res => {
this.setState({ data: res.data, loading: false });
})
.catch(console.error());
}
// Render the page
render() {
// Const
const { data } = this.state;
const project = data;
// Print to console (Debugging)
//console.log(data);
// Return Page
return (
<div className="projectDetailMainContainer">
<div className="projectDetailGrid">
<div className="projectDetailArea">
<div className="projectNameArea">
<h1 className="projectNameStyling">
{project.title}
</h1>
</div>
<div className="projectAddress1Area">
<h2 className="projectAddress1Styling">
{project.address},
</h2>
</div>
<div className="projectAddress2Area">
<h2 className="projectAddress2Styling">
{project.address2}
</h2>
</div>
<div className="projectCityArea">
<h2 className="projectCityStyling">
{project.city} {project.zipcode}
</h2>
</div>
<div className="projectProgressArea">
<h3 className="projectProgressStyling">
{project.completed}
</h3>
</div>
<div className="projectReturnButton">
<button
className="btnStyleDetailPage"
type="button"
onClick={() => { this.props.history.replace('/projects') }}>
Return to Project List
</button>
</div>
</div>
<div className="projectDetailImageArea">
<SRLWrapper>
<img className="projectImageStyling"
src={require("./placeholders/city.jpg")} alt={project.title} />
</SRLWrapper>
</div>
</div>
<Footer />
</div>
);
}
}
// Export Compoenent
export default ProjectDetail;
You can solve this by implementing a image carousel or iterating over the images array.
First of all you must guarantee that the pictures are properly set on a state (does not matter what type of component). Then, here is one way to show all of the images and solve the problem:
function ImageList(props) {
return (
props.images.map((pic, index) => {
return (
<img key={index} src={pic.src} alt="image" />
);
})
);
}
use map like this
{ data.map(project => { <div className="projectDetailMainContainer">
<div className="projectDetailGrid">
<div className="projectDetailArea">
<div className="projectNameArea">
<h1 className="projectNameStyling">
{project.title}
</h1>
</div>
<div className="projectAddress1Area">
<h2 className="projectAddress1Styling">
{project.address},
</h2>
</div>
<div className="projectAddress2Area">
<h2 className="projectAddress2Styling">
{project.address2}
</h2>
</div>
<div className="projectCityArea">
<h2 className="projectCityStyling">
{project.city} {project.zipcode}
</h2>
</div>
<div className="projectProgressArea">
<h3 className="projectProgressStyling">
{project.completed}
</h3>
</div>
<div className="projectReturnButton">
<button
className="btnStyleDetailPage"
type="button"
onClick={() => { this.props.history.replace('/projects') }}>
Return to Project List
</button>
</div>
</div>
<div className="projectDetailImageArea">
<SRLWrapper>
<img className="projectImageStyling"
src={require("./placeholders/city.jpg")}
alt={project.title} />
</SRLWrapper>
</div>
</div>
<Footer />
</div>
})}
for the images you can access them by index like this
{project.images[0].src}
{project.images[1].src}
{project.images[2].src}
example:
<img src={project.images[0].src} alt="image" />

Categories

Resources