Targeting window.location.pathname in Next.js - javascript

Do you know how to target window.location.pathname in NEXT.JS ?
I have this code and next.js shows me nice red err
const path = window.location.pathname
console.log(path) // here I am getting pathname
Than
{
path === '/product' ? <p className='mt-2'>Products</p> :
path === '/contact' ? <p className='mt-2'>Contact</p> :
path === '/cart' ? <p className='mt-2'>Cart</p> :
<p className='mt-2'>Home</p>
}

You can't use window.location.pathname in Next.js because the window object is not available on the server-side in Next.js. The server-side rendering of Next.js doesn't have access to the window object, which is a client-side object, because it doesn't run in a browser environment.
import { useRouter } from 'next/router';
And then use it inside your component.
const router = useRouter();
const path = router.pathname;
return (
path === '/product' ? (
<p className='mt-2'>Products</p>
) : path === '/contact' ? (
<p className='mt-2'>Contact</p>
) : path === '/cart' ? (
<p className='mt-2'>Cart</p>
) : (
<p className='mt-2'>Home</p>
)
//...
);

Related

React component appears and disappears instantly in conditional rendering

For following scenario :
When user don't have admin access, else case is rendering and disappearing instantly after it.
I can see blank page only after it.
How to resolve this scenario ?
function Component () {
const isAdmin = checkIsAdmin('user')
return (
{ isAdmin ? (
return <div>Show admin page</div>
) : (
return <h1>You are not autherized</h1>
)
}
)
}

Render a component in jsx if a certain condition is met

Really new to react, I have this part of navigation in my Navbar.js using react-router-dom useLocation hook, I am able to get the active path I have to views and I want to render custom text when a user arrives at the view with JSX something like
if(path==="login" || path==="signin"){
`<h1>welcome</h1> ${userName}!`
}
How can I check if condition A or B is met then render the appropriate text using jsx
You must explicitly tell what to return, in your example you do not return anything. So, You can do either :
if (path === "login" || path === "signin") {
return (
<>
<h1>welcome</h1> {userName}
</>
);
} else {
return null;
}
Or use operator && to conditionally render.
{
(path === "login" || path === "signin") && (
<>
<h1>welcome</h1> {username}
</>
);
}
Read more about conditional rendering [here]
You need to:
Return the value
Use JSX and not a string
Put everything in a container such as a React Fragment
Such:
if(path==="login" || path==="signin") {
return <>
<h1>Welcome</h1>
{userName}!
</>;
}
… but that logic should probably be handled by your routes rather than an if statement.
You can use the ternary operator for conditional rendering in JSX like
{path==="login" || path==="signin" ? <> <h1>welcome</h1> {userName} </> : null}
Simple :-)

Conditional rendering on React routes

I have several routes where different components are being rendered depending on the path as the following in my App.js
<Route
path="/spaces"
render={({ match: { url } }) => (
<>
<Route path={[`${url}`, `${url}/members`, `${url}/about`, `${url}/admin`]} component={Spaces} exact />
</>
)}
/>
<Route
path="/profile"
render={({ match: { url } }) => (
<>
<Route path={[`${url}`, `${url}/comments`, `${url}/spaces`, `${url}/cloud`]} component={Spaces} exact />
</>
)}
/>
In my Space.js component I have created a conditional rendering depending on the url, so when the user is in for example /spaces/members or /spaces/members/ a component will be rendered etc ..
function Spaces({ match }) {
let path = `${match.url}`;
let Content;
let admin;
let profile;
if (path == '/spaces/members/' || path == '/spaces/members') {
Content = <SpaceMembers />;
} else if (path == '/spaces/' || path == '/spaces') {
Content = <SpaceContent />;
} else if (path == '/spaces/about' || path == '/spaces/about/') {
Content = <SpaceAbout />;
} else if (path == '/spaces/admin' || path == '/spaces/admin/') {
admin = true;
Content = <SpaceAdmin />;
} else if (path == '/profile' || path == '/profile/') {
profile = true;
typeContent = <ProfileContent />
} else if (path == '/profile/comments' || path == '/profile/comments') {
profile = true;
Content = <ProfileSpace />
}
return (
<div>
<div className='page-content' style={{ maxWidth: !admin ? '980px': '800px'}}>
<div className='profile-page tx-13'>
{(!profile || admin) ? <Cover admin={admin} profile={profile}/> : <CoverProfile admin={admin} profile={profile}/> }
{Content}
</div>
</div>
</div>
);
}
export default Spaces;
For now the conditional rendering is working perfectly. But as a newbie in React my question is, is this the right thing to do or is there any other better method ?
For now I'm afraid that I will need to add a custom /:id later to the paths and the conditions might not work.
I suggest you to create a config file where you declare all the routes available to you and after that, create a routes file and import all the paths from path.js and create a list containing objects having all the props of which are - exact,component,path. In path,s value, call the paths you've imported from paths.js. what it will do is, it creates a good structure for you to deal with routing in general

Send value to child component in react

I have a component that takes a parameter that can be true or false, I put it in the console to check.
console.log(isContract);
//can be true ou false
I need to send this value through a form that will render another component.
This is the parent component:
return (
<Contract
savingsFactors={formValues.savingsFactors}
onFieldSubmit={...}
/>
)
And here in the internal component, if my value that came from the other component is true, I need to change the items
const Contract = ({ savingsFactors }) => (
<PutField
label={label}
placeholder={placeholder}
onBlur={...}
// if isContract === true, return this:
items={savingsFactors === 'true' ? FORM_VALUES : FORM_VALUES_NORMAL}
// if isContract === false, return this:
items={savingsFactors === 'true' ? ANOTHER_FORM_VALUES : ANOTHER_FORM_VALUES_NORMAL}
/>
);
What is the simplest way to send the isContract to the internal component and load the items according to the result?
I'm studying react and I'm having a lot of trouble with it, thanks a lot to those who help
I'm more familiar with defined props in React, but If I remember correctly, this should go something like this:
Edit 1
Added a render method inside the Contract component.
Edit 2
I just realized that you have a component inside your contract component XD which should be inside the render method itself. I think that might be the issue.
return (
<Contract
savingsFactors={formValues.savingsFactors}
isContract={isContract}
onFieldSubmit={...}
/>
)
And your component should be something like (After Edit 2):
const Contract = (props) => (
render(){
let items = [];
if (props.isContract === true)
{
items={props.savingsFactors === 'true' ? FORM_VALUES : FORM_VALUES_NORMAL}
}
//BTW, should this be !== true? :P
if (props.isContract === true)
{
items={props.savingsFactors === 'true' ? ANOTHER_FORM_VALUES : ANOTHER_FORM_VALUES_NORMAL}
}
return (
<div>
<h2>I have {items.length} items... or something...<h2>
<PutField
label={label}
placeholder={placeholder}
**items={items}** /*Maybe?*/
onBlur={...}
/>
</div>
)
}
);

Nextjs Warning: Expected server HTML to contain a matching <div> in <div> when using conditional rendering

There are similar questions posed here and on Google, but none with answers that fit my scenario.
Basically, I want to display a different searchbar in the header, depending on what page I am on. This is nextjs.
But when reloading the page, I get the error in console:
Warning: Expected server HTML to contain a matching <div> in <div>
First thing I tried was
const currentPath = Router.router?.route;
return (
<div className="sub-bar">
{currentPath === '/products' && (
<Search />
)}
{currentPath === '/baseballcards' && (
<SearchBaseballCards />
)}
</div>
);
That generates the error when reloading the page, even if I comment either of them out.
Next thing I tried was the ternary route:
<div className="sub-bar">
{currentPath === '/baseballcards' ? <SearchBaseballCards /> : <Search />}
</div>
This actually worked but ternary is no good because I only want the search bar on the /products and /baseballcards pages.
Final thing I tried was:
const currentPath = Router.router?.route;
let searchbar;
if (currentPath === '/baseballcards') {
searchbar = <SearchBaseballCards />
}
else if (currentPath === '/products') {
searchbar = <Search />
}
else {
searchbar = null;
}
return (
<div className="sub-bar">
{searchbar}
</div>
);
This gives me the original error when reloading the page, so back to square one.
https://reactjs.org/docs/conditional-rendering.html
Rather than accessing the Router object directly with Router.router?.route, use the router instance returned by the useRouter hook. This will ensure that the rendering between server and client is consistent.
import { useRouter } from 'next/router';
const SearchBar = () => {
const router = useRouter();
const currentPath = router.asPath;
return (
<div className="sub-bar">
{currentPath === '/products' && (
<Search />
)}
{currentPath === '/baseballcards' && (
<SearchBaseballCards />
)}
</div>
);
};

Categories

Resources