如何为所有页面复制nextjs getStaticProps()函数而不必重复所有页面

时间:2020-10-08 22:54:24

标签: javascript reactjs next.js

如何在不重复所有页面的情况下为所有页面复制nextjs getStaticProps()函数?

这些是我的页面和布局组件。我想在所有页面上添加一个全局函数,这可能吗?您可以添加全局getStaticProps函数吗?

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;

组件: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;

2 个答案:

答案 0 :(得分:0)

显然不可能:https://github.com/vercel/next.js/discussions/10949

您可以使用getInitialProps(但是您不能在构建时生成页面),也可以将代码抽象为一个函数,然后将其导入每个页面中。

答案 1 :(得分:0)

对我有用:

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;

非常感谢