Does React always load the components from top to bottom by default?
For example if I have this
class App extends Component {
render(){
return (
<div>
<h1>EXAMPLE</h1>
<First />
<Second />
<Third />
<Fourth />
</div>
)
}
}
Will the sequence of mounting by default be always
First, Second, Third, Fourth ....from top to bottom like shown above???
-Yes, React does use top to bottom approach.This approach is useful when react creates virtualDOM and updates it's own DOM.
-have look to this https://reactjs.org/docs/reconciliation.html
Related
First I apologize if this question has been answered elsewhere. I'm still learning.
Assuming we have a parent component that has children components inside of it, so :
in App.js:
<>
<Advertisement title="Free Shipping For Orders Above 150 USD ! " />
<NavBar />
<LandingSection />
<Featured />
<Explore />
<Shop />
<RecommendedVideos />
<AsSeenOn />
<Footer />
</>
Now, we all know that each component has it own css file, however, if I want to change specific CSS attributes/styles to fit with the new component and I just want it in this specific component, in our case it is App.js. What should I do ? any tutorials on this topic ?
Also ... What is the difference between using
import styles from './styles.css
className = {styles.someName}
and using
styled-components library ?
and most importantly, in professional/real-world apps, what method do developers use ?
Each component should use either css modules or styled component. That way style will be scoped to that component.
If you use plain css then it might clash with other components styles.
I have 3 components in nextjs and i want to achieve the below snippet in nextjs
<Route path="/" component={homePage} />
<Route path="/about" component={aboutPage} />
<Route path="/faq" component={faqPage} />
Q1. How can i do the same in nextjs without page refresh? (without react-router)
(Edit : some scholars are suggesting to read the docs but i have read it thoroughly and what i want is to pass a component along with the route)
Is this even possible in next js?
Q2: If i have url as /products?product_id=productid and on refresh if i want the url to be /products (basically i want to remove all params on refresh) What is the best practice to do this?
Thanks in advance
NextJS functions on a convention-based filesystem-based routing. You'd need to place your components in a directory structure that matches the routes you are wanting.
More details here:
https://nextjs.org/docs/routing/introduction
The Next.js docs don't really cover how to change away from <Route> components, however they have a lot of examples as code on how to do most things with Next.js. https://github.com/vercel/next.js/tree/canary/examples/layout-component
The below is what I used as an alternative to the component (there's no direct Next.js alternative).
_app.js
export default function MyApp({ Component, pageProps }) {
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout || ((page) => page)
return getLayout(<Component {...pageProps} />)
}
Any page:
import Layout from '../components/layout'
import Sidebar from '../components/sidebar'
export default function About() {
return (
<section>
<h2>Layout Example (About)</h2>
<p>
This example adds a property <code>getLayout</code> to your page,
allowing you to return a React component for the layout. This allows you
to define the layout on a per-page basis. Since we're returning a
function, we can have complex nested layouts if desired.
</p>
<p>
When navigating between pages, we want to persist page state (input
values, scroll position, etc) for a Single-Page Application (SPA)
experience.
</p>
<p>
This layout pattern will allow for state persistence because the React
component tree is persisted between page transitions. To preserve state,
we need to prevent the React component tree from being discarded between
page transitions.
</p>
<h3>Try It Out</h3>
<p>
To visualize this, try tying in the search input in the{' '}
<code>Sidebar</code> and then changing routes. You'll notice the input
state is persisted.
</p>
</section>
)
}
About.getLayout = function getLayout(page) {
return (
<Layout>
<Sidebar />
{page}
</Layout>
)
}
The main part for the layout that you want to wrap around the pages, components/layout.js:
import Head from 'next/head'
import styles from './layout.module.css'
export default function Layout({ children }) {
return (
<>
<Head>
<title>Layouts Example</title>
</Head>
<main className={styles.main}>{children}</main>
</>
)
}
What's happening is the _app.js wraps all pages inside the declared layout. Each page then defines what layout that page belongs to. The layout then accepts a page as the {children} prop object of which you can then render anywhere in your layout page.
Next uses filesystem based routing, your folder structure should look like
-- pages
-- index.js
-- about/index.js
-- faq/index.js
For the custom component part, make a component that's clickable, on click, use next builtin router to redirect
const router = useRouter();
router.push('/');
I am currently creating a Next.js project and currently have a custom Layout implemented. I would like to reset my header component when a new page is clicked so that the menu will go back to its default version. Does anyone know how to do this?
import { Fragment } from "react";
import Header from "./header";
import Footer from "./footer";
import classes from "./layout.module.css";
function Layout(props) {
return (
<Fragment>
<Header />
<main className={classes.body}>{props.children}</main>
<Footer className={classes.bottom} />
</Fragment>
);
}
export default Layout;
Yes, you can easily do it using key, which is super cool.
function Layout(props) {
return (
<Fragment>
<Header key={props.selectedRoutePathName} />
<main className={classes.body}>{props.children}</main>
<Footer className={classes.bottom} />
</Fragment>
);
}
You can select a unique value (in your case, route pathname) and pass it as a key to the Header component.
And when the route path name changes, React will think of it as a different component and create another one. So the Header component will get the default state as you expected.
You can check my code-sandbox here for reference.
https://codesandbox.io/s/react-hooks-counter-demo-forked-t1llj?file=/src/index.js
I've created a very simple Next.js-project with two pages.
Both pages include a basic layout component:
// Page Component
render() {
return (
<PageLayout>
This is page A
</PageLayout>
);
}
And PageLayout looks something like this:
// PageLayout
render() {
return (
<div>
<Header />
{this.props.children}
</div>
);
}
So both pages use PageLayout to render a basic template that also includes the same Header on both pages.
My problem is that the Header component is re-created when navigating between the two pages. I think this is bad not only from a performance point of view, but also because in this case all DOM-Nodes and all React components loose their local state.
So I would like to know if there is something I am missing or how we can create shared components between pages that are reused properly (at least if their state did not change, of course).
You have Two pages with common component:
Page A:
<A>
<Common />
</A>
Page B:
<B>
<Common />
</B>
From the React documentation:
Whenever the root elements have different types, React will tear down
the old tree and build the new tree from scratch. Going from <a> to
<img>, or from <Article> to <Comment>, or from <Button> to <div> - any
of those will lead to a full rebuild.
This is why you lose the state in Common (Header) component. Like I suggested in the comment you would have to use an external state like redux.
You have to create a component with the name of layout
// components/layout.js
import Navbar from './navbar'
import Footer from './footer'
export default function Layout({ children }) {
return (
<>
<Navbar />
<main>{children}</main>
<Footer />
</>
)
}
And then rap your _app.js component like this
// pages/_app.js
import Layout from '../components/layout'
export default function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
for more read https://nextjs.org/docs/basic-features/layouts
How can I specify that a component should be rendered absolutely before any other component?
I want to specify that <Footer /> and all the child components of footer should be rendered before any other components.
The reason I want this is because I have code that depends on the html that footer is rendering which means that the reference to <Footer /> is undefined in the other components if <Footer /> doesn't render first.
Here's an example:
export default class Layout extends React.Component {
...
render(){
return (
<Body />
<Footer /> //Render first
);
}
}
The only way I see for you do do that is:
Have the information about the render status for the footer in a state. (Let's assume your name it isFooterRendered and it is a boolean)
You set isFooterRendered to be false in the initial state.
You only render the children components when isFooterRendered is true
In componentDidMount you will have a reference to Footer, set isFooterRendered to be true.
(Some people claim that it's bad to setState on componentDidMount but in your case looks like a legit use case, aside from that React Docs expose a similar example)