Routing to a new page for each search result with React? - reactjs

I'm really new to React and I'm working on this webapp, where I managed to receive data from the Google Books API and managed to list the results when I search for it.
How do I make a new page for each book whenever the user clicks on one of the books?
The code looks like this so far:
renderSearchResults = () => {
const { results } = this.state;
if (Object.keys(results).length && results.length) {
return (
<div className='results-container'>
{results.map((result) => {
return (
<a
key={result.id}
href={result.previewLink}
className='result-item'
>
<div className='image-wrapper'>
<a href={result.volumeInfo.infoLink}>
<img
className='image'
src={result.volumeInfo.imageLinks.smallThumbnail}
alt={result.volumeInfo.infoLink}
/>
</a>
</div>
<h6 className='image-title'>{result.volumeInfo.title}</h6>
</a>
);
})}
</div>
);
}
};
Right now I made it so that when each book is clicked it will redirect to the Google page for each book, but I want to make it like the design below, where when the user clicks they will be redirected to a new page like this:
The design I want to develop
Let me know if you have a solution or if you need any other information in order to help me.
Other than that, have a great weekend!

Exist in html the target Attribute, u can use like this:
Visit W3Schools
for more information see this w3schools.com definition

Related

button not going to correct links

I am using react and doing my portfolio
when people click on the button to view my github repo or project it goes to the wrong place
const Project = () => {
return (
<div className='work-container'>
<h1 className='project-heading'>Projects</h1>
<div className='project-container'>
{ProjectData.map((val, ind) => {
return (
<ProjectCard
key={ind}
imagesource={val.imagesource}
title={val.title}
text={val.text}
view={val.view}
github={val.github}
/>
)
})}
</div>
</div>
)
}
this is what my data file contains
const ProjectData = [
{
imagesource: project1,
title: 'Diamond Devs Tech Blog',
text: 'A community of developers who can write blogs about code or ask questions Built out of a need for developers have a nice simple platform rather than the complex ones out there in the marketplace, this was for an assignment foor my Bootcamp was challenging as had to do the front and backend from scratch using tech that I am still getting used too.',
view: 'https://diamond-developers-tech-blog.herokuapp.com/',
github: 'https://github.com/breakfireaus/diamond-developers-tech-blog',
},
]
export default ProjectData
I tried the above and instead of going to view project or github it goes to for example
https://matthew-younger-portfolio.herokuapp.com/portfolio/https://diamond-developers-tech-blog.herokuapp.com/
instead of just
https://diamond-developers-tech-blog.herokuapp.com/
I have reviewed code from you github repo. What you are doing is using React router NavLink to move to an external website which you cannot do as you can use it move within your application Documentation
.
You can convert them to a tag in your Project Card and they will work fine. You can use target="_blank" if you want to open the link in new tab.
import "./ProjectCardStyle.css";
import React from "react";
import { Link } from "react-router-dom";
const ProjectCard = (props) => {
return (
<div className="project-card">
<img src={props.imagesource} alt="Project Imagery" />
<h2 className="project-title">{props.title}</h2>
<div className="project-details">
<p>{props.text}</p>
<div className="project-buttons">
<a target={"_blank"} href={props.view} className="btn">
VIEW
</a>
<a target={"_blank"} href={props.github} className="btn">
Github
</a>
</div>
</div>
</div>
);
};
export default ProjectCard;

How to pass button text content to another page in React?

I'm not really into React but I have to do a simply appointment page.
I've built a simple calendar
(screenshot). Every "hour" button links to another page where I want to show the chosen time.
<div className="dzisiaj dzien" >
Dziƛ <br></br>
<button className="godzina niedostepny"><s>14:15</s></button>
<Link to="/Page3">
<button className="godzina">15:00</button>
</Link>
<button className="godzina">16:00</button>
<button className="godzina niedostepny"><s>16:45</s></button>
</div>
I've just used a Link component to redirect to a next page, but I have no idea how to display the specific chosen hour. I'd really appreciate some code example.
edit:
I feel like I've messed something up somewhere since it still doesn't work.
Console says:
"Uncaught TypeError: Cannot read properties of undefined (reading 'state')"
for line 7 and 12 of page3
The Link component attribute to can also be an object with additional parameters. See the full documentation here: https://v5.reactrouter.com/web/api/Link
This allows you to do the following:
<Link to={{ pathname: "/page3", state: { time: "15:00" } }} >{ /** ... */ }</Link>
On the target component, you can access the state via props.location.state as follows:
const Page3 = (props) => {
const { time } = props.location.state;
return (
<div id="page3">
<Header/>
<div id="test">
<p>{ time }</p>
</div>
</div>
)
}

How to create a button that opens a new page with the option to return back to previous page [ReactJS

Right below the page you see a 'back to log' button. If someone clicks on that it will return to the left page. So in order to do so I thought using react router will do the job. But not sure how to fix that.Is there someone who can help me to point me to the right direction. Keep in mind that it will not open a new tab!
Link to working snippet to understand the bigger picture of my app. CodeSandBox snippet here
return (
<div>
{info.map((show: any) => {
console.log(show.show)
return (
<div key={show.show.id}>
<ReactMarkdown source={show.show.name}/>
{show.show.image && <img src={show.show.image.medium}/>}
{show.show.genres.map((showGenre: string, index: number) => {
return (
<div key={index}>
<ReactMarkdown source={showGenre}/>
</div>
)
})}
<div>
<Router>
<ul>
<li>
<Link to="/">See deta</Link>
</li>
</ul>
</Router>
</div>
</div>
)
})}
</div>
)
Check out this working example (I placed notes in each file):
https://codesandbox.io/s/modest-panini-hkzlv?file=/src/App.js
Overview:
there are several ways to do this
my suggestion is to use the history npm and create a history.js file
you will also need to use Router from react-router-dom
in your parent component, or in a Context provider, you can store your state
in the parent component, use react-router-dom Switch and Route to place routes
depending on implementation, conditionally render show route for async state update
in your search component, place all your Links using react-router-dom
on click Links should also update app's state of your specific selection
this selection gets passed to the show route/component
in the show component attach an on click that uses history.goBack and resets state
this might help you:
this.props.history.goBack();
it goes back to prev page

Gatsby page in page

I'm using gatsby js and trying to figure out how to have a page level side bar with Gatsby links that render a new component inside a div in the same page I can do this using react-router-dom but in Gatsby all I can find is how to create blog posts which is driving me nuts as every tutorial I find is the same blog post.
Here is my layout page /layouts/index.js
export default ({ children }) => (
<div id="layout">
<header>
<h3>Header</h3>
<MainNav />
</header>
{children()}
</div>
)
About Page
/pages/about.js
export default ({ location, match }) => {
console.log('location = ', location, 'match = ', match );
return (
<div id="about">
<SideBar />
<div id="content">
// . add child template or component for link clicked in sidebar
</div>
</div>
);
};
What I'm trying to do is when a user clicks on a link in the side bar stay on about but render a new component or template based on the gatsby-link clicked in the about sidebar.
The About SideBar component
/components/about/side-bar.js
const SideBar = () => {
return (
<div id="side-bar">
{/* <li><Link to='/about?sort=name'>work</Link></li> */}
<li><Link to="/about/work">work</Link></li>
<li><Link to='/about/hobbies'>hobbies</Link></li>
<li><Link to='/about/buildings'>buildings</Link></li>
</div>
)
}
Problem with the links above, they are trying to go to a new page called.
/about/work
This is not what I'm trying to do. Again I'm trying to make it stay on about but render a new component inside the content div.
Please help gatsby is so all over the place as far as docs goes. ok maybe its just me and not getting the docs clearly.
Thanks
UPDATE:
I tried adding a page suing createPage which works for me kind of but it doesn't pass the match.params id
gatsby-node.js
exports.createPages = ({ boundActionCreators }) => {
const { createPage } = boundActionCreators;
const myComponent = path.resolve('src/pages/about/index.js');
createPage({
path: '/about/:id',
component: myComponent
})
}
After a long time of trying to understand Gatsby and I can say I still don't as its docs are vast and not very clear. But once I started to look at the node-apis and onCreatePage it gave me some ideas. This is what the docs literally say.
onCreatePage
Called when a new page is created. This extension API is
useful for programmatically manipulating pages created by other
plugins e.g. if you want paths without trailing slashes.
So the only part in here that gives me a hint of this might be the key to helping me is this line. useful for programmatically manipulating pages created by other
plugins
Anyway this got me writing some code at least. Then about 3 hours later I found a plugin that was doing exactly what I was trying to do with this method. The plugin is called gatsby-plugin-create-client-paths key here is client-paths!!!!!
This makes life worth living! So in my case above I just wanted to be able to use Gatsby's router ( which is just react-router-dom behind the scenes), to pass me and id or value to routers match.params object. It still doesn't but what it does do is checks for any path after a prefix like /folder/ in my case '/about/work and recreate the page with a template component (in my case keep using pages/about/index.js), which is my template. Now that we have about/index.js rendering for ever link after /about/ then we can use some internal switch statement to handle the location that is been passed to /about/index.js. Still don't get match.params update but I do get props.location.pathname; which allows me to extract everything after the prefix to use in a switch statement to render my specific components based on the routes pathname. Enough rabbiting on here is a rough solution to show as an example.
So add the plugin as an npm install.
open up gatsby.config.js and add the below code to the exports.
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-create-client-paths`,
options: { prefixes: [`/about/*`] },
},
]
}
Then in my main about page pages/about/index
import React from "react";
import SideBar from '../../components/about/side-nav';
export default (props) => {
const { pathname } = props.location;
var n = pathname.lastIndexOf('/');
var pageId = pathname.substring(n + 1);
const page = () => {
switch(pageId){
case '':
return (
<div>Work Page</div>
);
case 'work':
return (
<div>Work Page</div>
);
case 'hobbies':
return (
<div>Hobbies Page</div>
);
case 'buildings':
return (
<div>buildings Page</div>
);
}
}
return (
<div id="about">
<SideBar />
<div id="content">
{page()}
</div>
</div>
);
};
Then in my sidebar I call it like this.
<li><Link to="/about/work">work</Link></li>
<li><Link to='/about/hobbies'>hobbies</Link></li>
<li><Link to='/about/buildings'>buildings</Link></li>
Hopefully this will help someone else out. After all this I'm starting to really question the bulk of gatsby especially with docs not been very clear. Based on the response to my question I guess not many people in stackoverflow's community are using Gatsby which is worrying when you need help. It does look like Gatsby's github community is very helpful but that should be for bug issues and not for questions like mine, but encouraging to see.
Hope this helps someone.

React Flux application not showing data correctly

I was trying to refactor my React application, which is using callbacks to flux.
I am almost done, but not able to solve a little bug. The application shows youtube videos by fetching data from youtube.
Now when the first time the application load, it is showing the videos correctly.
The select functionality is working fine and also the search functionality
But if i select a video after the first render and then do a search . It doesn't shows the first video of the search.
I know the issue is in this part of the code in video_detail.js file.
My git repo for this app git repo for youtube-player-flux
Please help me solve this little bug.
render() {
if (!this.state.item) {
return <li className="media-right">Loading...</li>;
}
let video;
Object.keys(this.state.userSelected).length === 0
? (video = this.state.item)
: (video = this.state.userSelected);
const videoId = video.id.videoId;
const url = `https://www.youtube.com/embed/${videoId}`;
return (
<div className="video-detail col-md-8">
<div className="embed-responsive embed-responsive-16by9">
<iframe className="embed-responsive-item" src={url} />
</div>
<div className="details">
<div>{video.snippet.title}</div>
<div>{video.snippet.description}</div>
</div>
</div>
);
}
}

Resources