简体   繁体   中英

How to replicate the nextjs getStaticProps() function for all pages without having to repeat all pages

How can I replicate the nextjs getStaticProps() function for all pages without having to repeat all pages?

These are my pages and my layout component. I wanted to add a global function to all pages, is that possible? Can you add a global getStaticProps function?

index.tsx

import Link from 'next/link';
import Layout from '../components/Layout';
import {InferGetStaticPropsType} from 'next';

function Index({data}: InferGetStaticPropsType<typeof getStaticProps>) {
  return (
    <Layout
      title="Página - Home"
      description="desenvolvimento web, web development, construção de sites"
      title_meta="desenvolvimento web, web development, construção de sites"
      description_meta="desenvolvimento web, web development, construção de sites"
      site_name="Rafael Web development"
      url="http://localhost:3000/"
      images={data}>
      <div>
        <h1>Hello Next.js INDEX</h1>
        <Link href="/sobre">
          <a>About</a>
        </Link>
        <main></main>
      </div>
    </Layout>
  );
}

export const getStaticProps = async () => {
  const res = await fetch(process.env.url_index);
  const data = await res.json();

  return {
    props: {data},
  };
};

export default Index;

contato.tsx

import Layout from "../components/Layout";
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import Alert from '@material-ui/lab/Alert';
import AlertTitle from "@material-ui/lab/AlertTitle";
import { InferGetStaticPropsType } from 'next';

function Contato({ data }: InferGetStaticPropsType<typeof getStaticProps>) {  
  return(
    <Layout title="Página - Contato" description="desenvolvimento web, web development, construção de sites" 
    title_meta="desenvolvimento web, web development, construção de sites"
    description_meta="desenvolvimento web, web development, construção de sites" site_name="Rafael Web development"
    url="http://localhost:3000/" images={data}>
        <div>
        <h1>Contato</h1>
        <form>
          <Alert severity="error" id="error_contact" style={{display:"none",marginBottom:20}}>Erros:<br /></Alert>
          <Alert severity="success" id="sucess_contact" style={{display:"none",marginBottom:20}}>
            <AlertTitle>Enviado com sucesso!</AlertTitle>
          </Alert>
          <TextField id="outlined-nome" label="Nome" name="nome" type="text" variant="outlined"  
          style={{width:"100%",paddingBottom:20}} />
          <TextField id="outlined-email" label="E-mail" name="email" type="text"  variant="outlined" 
          style={{width:"100%",paddingBottom:20}}  />
          <TextField id="outlined-assunto" label="Assunto" name="assunto" type="text" variant="outlined" 
          style={{width:"100%",paddingBottom:20}}  />
          <TextField id="outlined-texto" label="Texto" name="texto" type="text" variant="outlined" 
          multiline style={{width:"100%",paddingBottom:20}} />
          <Button variant="outlined" color="secondary" onClick={handleSubmit}>
            Enviar
          </Button>
        </form>
      </div>
    </Layout>);
}

const validateEmail = (email:string)=> {
  const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  return re.test(String(email).toLowerCase());
}

const setMessage = (item:string)=> {
  (document.getElementById("error_contact") as HTMLHtmlElement).style.display="flex";
  (document.getElementById("error_contact") as HTMLHtmlElement).style.flexDirection="row";
  (document.getElementById("error_contact") as HTMLHtmlElement).style.flexWrap="wrap";
  (document.getElementById("texto") as HTMLHtmlElement).innerHTML+= "<div>"+item+"</div><br />";
 
}

const handleSubmit = async (event)=>{
  event.preventDefault();
  let list: string[] = ["Nome","E-mail","Assunto","Texto"];
  let context : string[] = ["outlined-nome","outlined-email","outlined-assunto","outlined-texto"];

  (document.getElementById("error_contact") as HTMLHtmlElement).innerHTML+= "<div style='flex-grow: 1;flex-basis: 100%' id='texto'></div><br />";
  (document.getElementById("texto") as HTMLHtmlElement).innerHTML= "";
  (document.getElementById("sucess_contact") as HTMLHtmlElement).style.display="none";
  let cond:boolean = false;

  context.forEach(async(item, index)=>{ 
    let test : string = (document.getElementById(item) as HTMLInputElement).value;
    if(test.replace(/\s/g,"")===""){
      setMessage("Preencha o campo "+list[index]);
      cond=true;
    }
    
    if(item=="outlined-email"){ 
      let p = validateEmail(test);
      if(p==false){
         setMessage("E-mail invalido!");
         cond=true;
      }
      
    }
  });

  if(cond==false){
    (document.getElementById("error_contact") as HTMLHtmlElement).style.display="none";

    let datas:any = {nome: (document.getElementById("outlined-nome") as HTMLInputElement).value, 
    email: (document.getElementById("outlined-email") as HTMLInputElement).value,
    assunto: (document.getElementById("outlined-assunto") as HTMLInputElement).value,
    texto: (document.getElementById("outlined-texto") as HTMLInputElement).value};
  
    try {
      let res = await fetch(process.env.url_contact, {
        method: 'post',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        }, 
        body: JSON.stringify(datas),
        credentials:"same-origin"
      });
      
      if(res.ok==true){
        (document.getElementById("sucess_contact") as HTMLHtmlElement).style.display="flex";
      }
    }catch(error){
      alert(error);
    }
  }
 
}

export const getStaticProps = async () => {
  const res = await fetch(process.env.url_index);
  const data = await res.json();

  return {
    props: { data }
  }
}



export default Contato;

component: Layout.tsx

import Header from "./Header";
import NavBar from "./NavBar";
import Head from 'next/head';


const Layout = (props:any) => (
  <div>
    <Head>
      <title>{props.title}</title>
      <meta name="description" content={props.description} />
      <meta property="og:type" content="website" />
      <meta name="og:title" property="og:title" content={props.title_meta} />
      <meta name="og:description" property="og:description" content={props.description_meta} />
      <meta property="og:site_name" content={props.site_name} />
      <meta property="og:url" content={props.url} />  
      <link rel="shortcut icon" href="/icon_OaB_icon.ico" />
    </Head>
    <Header images={props.images} />
    <div className="layoutStyle">
      <NavBar />
      <div className="Content">
        {props.children}
      </div>
    </div>
  </div>
);


export default Layout;

Apparently it's not possible: https://github.com/vercel/next.js/discussions/10949

You could either use getInitialProps (but then you can't generate pages at build time), or you can just abstract the code to a function and import it in each page.

it works for me:

functions/getInitialProps.tsx:

let init=(context:any,url:string)=>{
    
    context.getInitialProps = async () => {
        const res = await fetch(url);
        const data = await res.json();
      
        return {
          props: { data }
        }
      }
}

export default init;

index.tsx:

    import Link from 'next/link';
import Layout from "../components/Layout";
import { NextPage } from 'next';
import init from "../functions/getInitialProps";

interface Props {
  props?: any;
}

const index: NextPage<Props> = ({ props }) => ( 
    <Layout title="Página - Home" description="desenvolvimento web, web development, construção de sites" 
    title_meta="desenvolvimento web, web development, construção de sites"
    description_meta="desenvolvimento web, web development, construção de sites" site_name="Rafael Web development"
    url="http://localhost:3000/" images={props.data}>
        <div>
        <h1>Hello Next.js INDEX</h1>
        <Link href="/sobre">
          <a>About</a>
        </Link>
        <main>
        
        </main>
      </div>
    </Layout>
);

init(index,process.env.url_index);

export default index;

thank you very much

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM