1

I am trying to learn how to use next.js to render a component inside a layout, when a link is clicked.

I have a layout as follows:

import * as React from "react"
import { Box } from "@chakra-ui/layout"

import { Limiter } from "./Limiter"
import { Nav } from "./Nav"
import {Footer} from "components/footer/index"

interface Props {
  children: React.ReactNode
}

export function HomeLayout(props: Props) {
  return (
    <Box>
      <Nav />
      <Limiter pt="65px">{props.children}</Limiter>
      <Footer />
    </Box>
  )
}

I want to keep the nav and the footer components constant, and then when a link the footer is clicked, I want the href to populate the above props.children with the component that has the text for the link that has been clicked. I can find tutorials showing how to render a new page when the link is clicked, but I cannot find one that shows me how to use props.children (i still can't make sense of what those words actually mean to know what search terms I should be using to investigate the underlying principle) to render a specific component, but still showing the nav and the footer.

I have a footer that has:

import {
    Box,
    Button,
    ButtonGroup,
    Container,
    Divider,
    IconButton,
    SimpleGrid,
    Stack,
    Text,
  } from '@chakra-ui/react'
  import * as React from 'react'
  import { Logo } from '../../components/Logo'
  import { links } from './_data'
  
  export const Footer = () => (
   
    <Box
      w="100%"
      mt={10}
      borderTop="1px solid"
      borderColor="gray.200"
      zIndex={500}
    >
      <Box w="80%" ml="10%">
        
                <Stack
                justify="space-between"
                align="start"
                direction={{ base: 'column', lg: 'row' }}
                py={{ base: '12', md: '16' }}
                spacing="8"
                >
                <Stack spacing={{ base: '6', md: '8' }} align="start">
                    <Logo />
                   
                </Stack>
                <SimpleGrid columns={{ base: 3 }} gap="20" width={{ base: 'full', lg: 'auto' }} >
                    {links.map((group, idx) => (
                    <Stack key={idx} spacing="4" minW={{ lg: '40' }} >
                        <Text fontSize="sm" fontWeight="semibold" >
                        {group.title}
                        </Text>
                        <Stack spacing="3" shouldWrapChildren>
                        {group.links.map((link, idx) => (
                            <Button 
                                key={idx} 
                                as="a" 
                                variant="link" 
                                href={link.href} 
                                fontWeight="normal" 
                                color="brand.sludge"
                                _hover={{
                                    color: "green"}}
                            >
                            {link.label}
                            </Button>
                        ))}
                        </Stack>
                    </Stack>
                    ))}
                </SimpleGrid>
                </Stack>
                
      </Box>
    </Box>
  )

My _data.tsx file then has:

export const links = [
    {
      title: 'Company',
      links: [
        { label: 'About us', href: '' },
        { label: 'Contact', href: '#' },
       
      ],
    },
]

My goal is to populate the screen (in between nav and footer) with a component that has text to render if About us is clicked, and then a different component with text if contact is clicked.

I am stuck in trying to find a way to do this - because all the tutorials assume that I want to make a new page. Is there a way to keep the nav and foooter from reloading?

juliomalves
  • 42,130
  • 20
  • 150
  • 146
Mel
  • 2,481
  • 26
  • 113
  • 273

1 Answers1

0

If I understood correctly, I think that you have chosen the wrong logic for solving your problem. But if you want to save variables after navigating to another page, you can use local storage or cookies for this purpose.


The children is easy to understand for example:

<Component>
    <MyCustomChildren/> // props.children this is the given component passed as ReactNode
</Component>
Spell
  • 21
  • 3
  • Hi Spell, thank you. I don't understand what you mean by saving variables after navigating to another page. I want to click on a link in the footer and have the child component in the layout be populated with the component content for that link. I can find examples of how to do this for new pages to follow, but I cannot find an example for how to do this if instead of a page, I render a component. – Mel Oct 17 '22 at 20:41
  • I do not understand why this is necessary, do you have an example? – Spell Oct 17 '22 at 21:04
  • As described, I have a layout, that has a nav and footer, and now I'm trying to figure out how to display the text, for each link listed in the footer, in between the nav and footer in that layout. I only want to do that, if the footer link is clicked. – Mel Oct 18 '22 at 02:43
  • I created sandbox: [https://stackblitz.com/edit/nextjs-ykxxqf](https://stackblitz.com/edit/nextjs-ykxxqf) Is this what you want? If so, I'll edit my answer. – Spell Oct 18 '22 at 11:44