I built a site with nextjs (with server express & API) and Reactjs.
I would like to create dynamic paginations because there is far too much result for statically generated, So I added server endpoint /publiations/page/:id, I put a getInitialsProps for keep the id in query
But actually, when I click on my main page /publications where my store is not empty to go to the next page (publications/page/1), the page reloads and the store is empty. How I can keep my store when I change route?
And here my publications/page/[id].js
const PublicationsPage = ({id}) => {
return (
<>
<MainMenu/>
<Search/>
<div className="flex">
<Sidebar fallback={<Loader/>}/>
<Cards type={'publications'} idPage={id} />
</div>
</>
)
}
PublicationsPage.getInitialProps = async function({ query: { id } }) {
return {
id: id
};
};
export default withAuthSync(PublicationsPage);
The cards components where i use the data of store :
components/Cards.js
const Cards = ({ idPage, cards, type }) => {
console.log(cards)
return (
<div className="cards">
<div className="content-filter-search">
<div className="content-newsearchresult">
<div className="global-name">Result: {cards.cards.length} articles found</div>
<div className="content-button-blue">
<Link href="/explorer">
<a>
<div className="button-blue">New search</div>
</a>
</Link>
</div>
</div>
<div className="content-filter">
{filters[idPage].map((item) => {
return <InputFilter key={item.id} data={item} callback={keepItems} />;
})}
</div>
</div>
<div className="wrapper-card">
<div className="cards-container">
{
!cards.loading ? cards.cards.slice(idPage * 9, idPage * 9 + 9).map((card) => (
<Card key={card.PMCID} data={card} />
)) : <Spinner color="black" size="100px" thickness={3} gap={5} speed="fast" />
}
</div>
</div>
<div className="text">
<Link href={'/publications/page/1'}><a>Next page</a></Link>
</div>
{
!cards.loading ? (
<div className="center">
<Pagination type={type} page={parseInt(idPage)} totalElement={cards.cards.length} numberPerPage={9} />
</div>
) : null
}
</div>
);
};
const mapStateToProps = state => ({
cards: state.cards,
})
export default connect(mapStateToProps)(Cards);
I use the same code for the route /publications and /publications/page/:id just I add the getInitialProps to keep the id of page. And I use connect redux in my Cards component
I have no error in the console just my store is reset because the page reload. I don't understand how I can make pagination with my store where is my data if when I change page the store is empty
Thanks
Related
In reactjs, what code would I have to write in my two components(homepage.js with an add-to-cart button and a checkout page with a clear cart button? This is my Homepage.js where I fetch the items from my backend server, map, and display them on the page.
function Home() {
const [data, setData] = useState([]);
useEffect(() => {
// auto-login
fetch("/coffees").then((res) => {
if (res.ok) {
res.json().then((data) => setData(data))
}
});
}, [])
console.log(data)
return (
<>
<div className="box">
<div className="projo">
<h2 >Welcome to Coffee-cafe</h2>
</div>
<div className="projects">
{data.map((data) =>{
return(
<div className="card">
<img className="avatar" src={data.coffee_image} alt="coffee"></img>
<div className="card-content">
<h4><b>{data.coffee_name}</b></h4>
<p id="desc">{data.description}</p>
<p className="price">{data.price}</p>
{/* <p>{data.category}</p> */}
<button onClick={() => ({})} className="btn1" id="btn1">Add to Cart</button>
</div>
</div>
)
})}
</div>
</div>
</>
)
}
export default Home;
For the Checkout.js, this is what I have currently.
function Checkout() {
return (
<>
<div className="section">
<div className="photo">
<img className="dp" src={image1} alt="coffee"></img>
<div className="info">
<h3>Coffee:</h3>
<p>Price:</p>
<p>Category:</p>
<div className="check-out-btn">
{/* <button className="add">AddToCart</button> */}
<button className="delete">ClearCart</button>
</div>
</div>
</div>
</div>
take a look for a global states like redux , context,or zustand
for my recommendation, I suggest zustand is less code than context and redux and short learning curve
carts =[]
setItemToCart(item){
const isExist = carts.find(c => c.id ===item.id)
if(isExit){
const qty = isExit.qty+item.qty
const newItem= {...item,qty}
// push is not recommended to use because it mutates state
carts.push(newItem)
}else{
carts.push(item)
}
}
When i refresh the page props value is not shown. Is this possible to show props value where we left it before the refresh the page?
Code:-.
Parent component
const LeftNav = () => {
return (
<div className="allDivs">
{item.map((items, index) => {
// console.log(item)
return (
<div key={index} >
<TabHeader item={items} index={index}/>
</div>
)
})}
</div>
</div >
)
}
export default LeftNav;
Child componentL;-
export default function TabHeader({ item, index }) {
return (
<Fragment>
<div id="CLOSEDIV">
<div className="TableText" onClick={(e) => { handleOnClick(e, Delete.val) }}>
<div id="SHOW">{Delete.val}</div>
</div>
</div>
</Fragment >
)
}
please help..
When you refresh the page, the browser will flush all the in memory javascript and react must initialize again.
To persist data between reloads you can use the Web Storage API.
How can I pass map items (title, category and images) in my id.jsx file.
Basically, I just want to create a single page for my projects. But I can only access post ID. I don't know how to pass other data items.
'Projects folder'
[id].js
import { useRouter } from "next/router";
const Details = () => {
const router = useRouter();
return <div>Post #{router.query.id}
// Single Project Title = {project.title} (like this)
</div>;
};
export default Details;
index.js
import { MyProjects } from "./MyProjects";
const Projects = () => {
const [projects, setProjects] = useState(MyProjects);
{projects.map((project) => (
<Link
href={"/projects/" + project.id}
key={project.id}
passHref={true}
>
<div className="project__item">
<div className="project__image">
<Image src={project.image} alt="project" />
</div>
<div className="project_info">
<h5>{project.category}</h5>
<h3>{project.title}</h3>
</div>
</div>
</Link>
))}
If I understand your question correctly, you want to send some "state" along with the route transition. This can be accomplished using an href object with the "state" on the query property, and the as prop to hide the query string.
Example:
{projects.map((project) => (
<Link
key={project.id}
href={{
pathname: "/projects/" + project.id,
query: {
id: project.id,
category: project.category,
title: project.title
}
}}
passHref={true}
as={"/projects/" + project.id}
>
<div className="project__item">
<div className="project__image">
<Image src={project.image} alt="project" />
</div>
<div className="project_info">
<h5>{project.category}</h5>
<h3>{project.title}</h3>
</div>
</div>
</Link>
))}
...
const Details = () => {
const router = useRouter();
return (
<div>
<div>Post #{router.query.id}</div>
<div>Title {router.query.title}</div>
<div>Category {router.query.category}</div>
</div>
);
};
I am using Next Js (React Js) to develop my Web app here, I have also used graphql to get my data from database I am also getting it but not able to render it on screen. What should I do!
import Link from 'next/link'
import moment from 'moment'
import {getRecentPosts , getSimilarPosts} from '../../services'
const PostWidget = ({categories , slug}) => {
const [relatedPosts, setRelatedPosts] = useState([])
useEffect(() => {
if(slug){
getSimilarPosts(categories, slug).then((result) => setRelatedPosts(result))
}
else{
getRecentPosts().then((result) => setRelatedPosts(result))
}
}, [slug])
return (
<div>
<h3>
{slug ? "Related Posts" : "Recent Posts"}
</h3>
{relatedPosts.map((post) =>{
<div key={post.slug}>
<div className="image">
<img
src={post.featuredImage.url}
alt="" />
</div>
<div className="content">
<p>{moment(post.createdAt).format('MMM DD, YYYY')}</p>
<h3>{post.title.toString()}</h3>
</div>
</div>
})}
</div>
)
}
export default PostWidget
When I console.log(relatedPosts) this I am able to get the data in json format but when I try to use it like above I am not getting the post information and am not able to show my data in my web page
{relatedPosts.map((post) => (
<div key={post.slug}>
<div className="image">
<img
src={post.featuredImage.url}
alt=""
/>
</div>
<div className="content">
<p>{moment(post.createdAt).format('MMM DD, YYYY')}</p>
<h3>{post.title}</h3>
</div>
</div>
))}
Because I inserted a {curly bracket} instead of a (paranthesis):
(post)=>{ code/JSX } ❌
We can correct this in two ways :
(post)=>{ return ( code/JSX )} ✔
or
(post)=>( code/ JSX(react/next) ) ✔
I am creating a details page to load json data for a specific id from earthquake list. The home.js file contains the state and the routes and the list of earthquakes which are links to the detail page. The detail.js page should show the details of each earthquake for the link clicked.
I am getting the state and data in the console but it is not displaying on frontend.
I want the link in the home page to display the detail page for that particular earthquake id.
The state is passed through posts from { Home } component to the { Detail } component and I am reading JSON through require.
Please help. I would really appreciate it!
Home.js
const Home = (props) => {
const posts = require('/src/components/features.json');
console.log(posts)
return (
<>
<Container fluid={true}>
<Row>
<CardDeck className=" no-gutters ">
{randomData.map((random) => {
return (
<div key={random.metadata.api}>
<h2>{random.metadata.title}</h2>
</div>
)
})}
{posts.map((postData) => {
console.log(postData.id);
return (
<HashRouter>
<div key={postData.id} className="container">
<ul className="a">
<li>
<Link to={{
pathname: `/detail/${postData.id}`,
state: {posts : postData}
}}
>
{postData.properties.title}</Link>
</li>
</ul>
<Route
path="/detail/:id"
name="earth"
component={Detail}
exact
/>
<li className="b">
{postData.properties.mag}
</li>
<li className="c">
{postData.properties.time}
</li>
</div>
</HashRouter>
);
})}
</CardDeck>
</Row>
</Container>
</>
);
}
export default Home
Detail.js
const Detail = ()=> {
const { state } = useLocation();
console.log(state)
return (
<div>
<div>
<strong>Id:</strong> {state.posts.id}{" "}
</div>
<div>
<strong>Name:</strong> {state.posts.properties.mag}{" "}
</div>
<Link to="/">
<button>Back</button>
</Link>
</div>
);
};
export default Detail;