Setting parameters in LINK reactjs - reactjs

I would like to pass information through the Link tag to another component . However , i am unable to after watching several tutorials .
function Productscard(props) {
return (
<div className="item">
<Link to = "/products_info">
<div className="item_container">
<h3 className="subcategory_Tag"> {props.subcategory}</h3>
<h2 className="name_tag"> {props.name}</h2>
<img src={photo} alt="" className="photo" />
<h3 className="price_tag">$399.99 - $500</h3>
</div>
</Link>
</div>)
}
export default Productscard
There are several Productscard components being rendered on the page . Upon being clicked , they should take me to the products_info page and display product name and description . I have attempted unsuccessfully and below is my product_info component -
function Product_info(props) {
const params = useParams();
return (
<div className="product_info">
<h1>
{params.name}
</h1>
</div>
)
}
export default Product_info
I have also set the route in app js
<Route path="/products_info element={<Product_info />}/>
I have tried the above code unsuccessfully

Related

How to solve react hydration error in Nextjs

I have created small nextjs page using wordpress REST API, Now react-hydration-error error show this page.I am using react html parser npm. How do I solve this error. could you please solve this error.
my code:
import Image from 'next/image'
import React ,{Component}from 'react'
import Link from 'next/link';
import { BiCalendar } from "react-icons/bi";
import ReactHtmlParser from 'react-html-parser';
export default class Blog extends Component{
constructor(props){
super(props);
this.state={
data: props.bloglist,
isLoading: true,
dataLoaded: false,
};
}
render(){
if (!this.state.data) {
return null;
}
console.log(this.state.data)
return(
<>
<div className="container blog-section">
<div className='row'>
<h2>Latest Posts</h2>
</div>
<div className='row'>
{
this.state.data.map(((x,i) =>(
<div className='col-md-4 boxs text-center' key={i}>
<div className='bg-info'>
<img src={x.images.large} className='img-fluid'/>
<h3>{x.title.rendered} </h3>
<p className='shopping'><span><BiCalendar/> {x.date}</span> </p>
{/* <p dangerouslySetInnerHTML={{__html: x.excerpt.rendered}}></p><span><BiShoppingBag/> {x.slug}</span> */}
<p class='expert'>{ReactHtmlParser(x.excerpt.rendered)}</p>
<Link href={"/blog"+"/"+x.slug+"/"+x.id } passHref={true}><p className='readmore'><span>Readmore </span></p></Link>
</div>
</div>
)))
}
</div>
</div>
</>
)
}
}
My original issues:
paragraph coming this format <p>If you have heard that there are ways to make money while shopping in the UAE and would lik</p> from API, So I converted to html.
I had this error, in my case I had <p> tag nested inside another <p> tag,
I was using Typography (MUI v5) to render text, switching to <Box> from <Typography> fixed the error.
We use components to build the React-based websites, These components are made using HTML tags. It is very important not to nest the same HTML elements.
For Example:
function Logo() {
return (
<Link href="/">
<a>
<Image
src="/images/logo.svg"
width={100}
height={75}
/>
</a>
</Link>
);
}
export default Logo;
Above is the Logo Component which has already the <a></a> tag inside it.
In this example, you will get the React Hydration Error if the <a> tag is used inside another <a> tag.
<a href="#">
<Logo />
</a>
So do not include the same HTML tags, which are hidden inside the
components to avoid react hydration error.
In my case I am using NextJS and I had a dropdown with react-select, the default value was changing after a small calculation, that does not like to nextjs, this is my previous code:
<Select options={seasons}
onChange={() => setSeason(e.value)}
defaultValue={seasons.find((x) => x.value == season) ? seasons.find((x) => x.value == season) : seasons[0]}
/>
So, I changed that calculation to the useEffect and initialized the react-select dropdown only when that value was calculated,now this is my current code that works:
{defaultSeason && (<Select options={seasons}
onChange={() => setSeason(e.value)}
defaultValue={defaultSeason}
/>)}
So, basically check that the defaultValue or anything else does not change after the html is sent to the client part in NextJS.
Follow these: https://nextjs.org/docs/messages/react-hydration-error
Or try deleting <a> within <Link> maybe.
My first code was this:
const isUserLoggedIn = is_user_logged_in()
// is_user_logged_in() checks for cookie of user token and returns boolean
Got the error about hydration
Then changed code to this:
const [isUserLoggedIn, setIsUserLoggedIn] = useState(null)
useEffect(() => {
setIsUserLoggedIn(is_user_logged_in())
}, [])
Renders was like this:
{isUserLoggedIn ? (
<>
{/* After login */}
<Profile USER={USER}/>
</>
) : (
<>
{/* Before login */}
<SigninButtons/>
</>
)}
And error solved
You can also check this
https://nextjs.org/docs/messages/react-hydration-error
Just try restarting the server. npm run dev. It worked for me. I was using react-hot-toaster.
Also try to check if you have sth like this:
<p>
<div>
Hello
</div>
</p>
div cant be inside p tag

Passing objects to navigation / .map objects single page component

I am learning React and I have a problem that I don't know how to solve, so If you can please help me with it.
I want to create a simple react app, where I create 3 components with .map() method. I would like to pass the data to Head component that I can access to every single card separately.
I have used .map() method but all cards are on one page. Can I do that with .map() method, and pass data to nav component?
function Card(props) {
return (
<Router>
<div id="wrapper">
<Link to="#"><button id="request" href="#">
REQUEST
</button></Link>
<h1 id="naslov">{props.name}</h1>
<p>{props.key}</p>
<div id="povez">
<a id="srcek"><FiHeart /></a>
<button id="follow">Follow</button>
<a id="kocka"><FiExternalLink /></a>
</div>
<div>
<h4 className="he4der">ORIGIN</h4>
<button id="origin">COUNTRY</button>
</div>
<div>
<h4 className="he4der">GENRE</h4>
<button id="origin">ROCK</button>
</div>
<div>
<h4 className="he4der">SUBGENRES</h4>
<button id="origin">ROCK</button>
<button id="origin2">METAL</button>
</div>
<div>
<button id="origin">ROCK</button>
<a id="kocka2"><FiExternalLink /></a>
</div>
<div id="breaker"></div>
<div id="socialinks">
<div id="social">
<span id="sicon"><FaFacebookF /></span>
<span id="sicon"><FaTwitter /></span>
<span id="sicon"><FaInstagram /></span>
<span id="sicon"><FaSpotify /></span>
</div>
<div id="plus">
<a id="kocka2"><FiExternalLink /></a>
</div>
</div>
</div>
)
}
export default Card
I would like to pass artist_name to nav component, so that when I
click on that name I can access card component that is related to that
name/artist.
Instead of passing a single artist it may make more sense to use all_artists and map your links. If all_artists isn't available globally it can be passed as a prop.
const Head = (props) => {
return (
<div id="header">
<img src={Logo} id="logo" />
<ul>
{props.artists.map(({ artist_id, artist_name }) => (
<li key={artist_id}>
<Link to={`/artist/${artist_name}`}>{artist_name}</Link>
</li>
)}
</ul>
<div id="icns">
<i><FiSearch /></i>
<i><FiAlignJustify /></i>
</div>
</div>
)
}
Pass all_artists to Head and render a dynamic route to extract name from the path to be passed on to Card on the name prop. Notice the Router was moved here to provide a routing context for both the Link components in Head and the Route component in App.
function App() {
return (
<div className="App">
<Router>
<Head artists={all_artists} />
<Route
path="/artist/:name"
render={({ match: { params: { name } } }) => (
<Card name={name}>
)}
/>
</Router>
</div>
);
}
Card will need to utilize a lifecycle to "react" to any changes on the name prop, like fetching/loading specific artist data from an API endpoint or redux state.
You need to pass to your component(that is rendering the card) what is the artist_id( as props) that you want to display and then you could use find() array method to search/filter the object that you need inside the array since you already have the ID of the artist.
and you might want to use switch and map() method on your router if you want all artist to be in your navigation
something like this:
<Switch>
{ all_artists.map( artist =>
<Route path=`/{artist.id}` render={ <CardComponent clickedArtist={artist} /> }/>
)}
</Switch>

Can't get components displayed with react-scroll navigation

I'm using react-scroll to navigate to different sections on the same page. I've been following a tutorial and everything works but I have dummy text in each section and now I don't know how to change the content to my components. Basically I have three components and I want one to be displayed in each section of my web page but I can't get it working.
I don't want title, subtitle, dark etc in each section. Instead I want to just put my whole component in that section.
Can someone show me how I would put one of my components in each section (there are three components and three sections)? Is this possible or do I have to re-structure my website so that the content is separated in to different parts like shown in section.js?
Important: The part which I don't understand is how to link up my content in Section.js:
Section.js
import React from "react";
export default function Section({ title, subtitle, dark, id }) {
return (
<div className={"section" + (dark ? " section-dark" : "")}>
<div className="section-content" id={id}>
<h1>{title}</h1>
<p>{subtitle}</p>
</div>
</div>
);
}
App.js
class App extends Component {
render() {
return (
<div className="App">
<Navbar />
<Section
title="section1"
subtitle={dummyText}
id="section1"
/>
<Section
title="section2"
subtitle={dummyText}
dark={false}
id="section2"
/>
<Section
title="section3"
subtitle={dummyText}
dark={true}
id="section3"
/>
</div>
Navbar.js
<nav className="nav" id="navbar">
<div className="nav-content">
<button
className="nav-logo"
alt="Logo"
onClick={this.scrollToTop}
>Top</button>
<ul className="nav-items">
<li className="nav-item">
<Link
activeClass="active"
to="section1"
spy={true}
smooth={true}
offset={-70}
duration={500}
>
About
</Link>
</li>
Do you need to pass a component to your Section Component instead of these params?
{ title, subtitle, dark, id }
if this is a case, you can use children
export default function Section({ children }) {
return (
<div>
{children}
</div>
);
}
then you can put your component here:
<div className="App">
<Section>
// your component
</Section>
</div>

How do you change content of page when the link is inside of the component?

Sorry in advance if I seem confused, it's because I am.
So from my App.js file which is like the main file where I call all my components and query my DB, which is then called by the index.js file.
this is my render method.
render() {
return (
<div className="site" >
{
!!!this.state.done ? (
<LoadingSVG />
) : (
<div className="page">
<div className="header-wrapper">
<Header data={this.state.dataHeader} />
</div>
<div className="project-list-wrapper">
<ProjectList data={this.state.dataProjects} />
</div>
</div>
)
}
</div >
)
}
Inside the Projectlist component I loop through every items and create a project.
render() {
return (
<div className="project-list module">
<div className="sectionTitle">Project I've worked on</div>
{this.props.data.map((res, i) => (
<div className="project-wrapper">
<div className="inner-ctn">
<div className="header">
<div className="number">0{res.id + 1}</div>
<div className="name">{res.nomProjet}</div>
</div>
<div className="item-ctn">
<div className="categ">{res.categProjet}</div>
<div className="roles">{res.roles}</div>
<div className="date">{res.date}</div>
</div>
</div>
</div>
))
}
</div>
);
}
What I want to do is with the use of transition-groups, render another component.. let's call it Project-1. Project 1 would refresh my App.js content so that the new component would render. But I can't do that since App.js is parent to ProjectList. I also want to keep a well structure project so I don't want to put everything in a single file..
I tried reading the documentation and basically every article about how to do this, I can't seem to wrap my mind around how this should work. This should be easy stuff, yet it's weirdly complicated to have a transition or even a link between two pages..

Materialize Tabs not working using React Router

I am trying to understand why Materialize tabs won't work when I am using react router.
I have 3 options on the navigation bar that will open their respective pages: "Hotels", "Statistics" and "Academy".
Each of these sections has tabs inside them.
Inside Hotels, I have 3 materialize tabs: Gen Info, Staff, Content and on the other pages I also have materialized tabs.
They work perfectly when used outside react router. This is the code:
class App extends Component {
render() {
return (
<div className="App">
<Navbar/>
<div className="body-extranet">
<Header/>
<Switch>
<Route path="/hotels" render={() => (
<PageHotel tab={"Hoteis"}/>
)}>
</Route>
<Route path="/statistics/" render={() => (
<PageStatistics tab={"Statistics"}/>
)}>
</Route>
<Route path="/academy/" render={() => (
<PageAcademy tab={"Academy"}/>
)}>
</Route>
</Switch>
</div>
</div>
);
}
}
export default App;
Inside PageHotel Component, for instance, I have the materialize tab
class PageHotel extends Component {
render() {
const { hotel, tab } = this.props;
return (
<div className="page">
<div className="subheader-tabs">
<div class="row">
<div class="col s12">
<ul class="tabs">
<li class="tab col">General Info</li>
<li class="tab col">Staff</li>
<li class="tab col">Content</li>
</ul>
<div className="divider"></div>
</div>
<div id="info" class="col s12">
<div className="container">
<Form></Form>
</div>
</div>
<div id="staff" class="col s12">
<Staff></Staff>
</div>
<div id="content" class="col s12">
</div>
</div>
</div>
</div>
);
}}
When I click on hotels on the navbar the materialize tab is not even started and the contents of all tabs are spread on a single page. I have to reload the page once to get it to work properly.
I tried using react-materialize and it started to work, However, I ran into other problem. One of them tabs has a controlled form which updates redux store once the local state is changed. However, whenever I write something inside the form the form reloads and I am not able to write anything.
Does anyone know why this is happening?
That becouse de materialize-js file is just being loaded at page loading and when you use react-routes the page isn't being loaded so the file can't initialize it and the tabs are broken. you must implement something like this:
Materialize-css With React, Initializing components using React Lifecycle method

Resources