reactnext.js

next.js基础

# 博客文章

https://github.com/lovelts/next-blog

https://github.com/HessTina-YuI/yui-old-blog

# 项目

redux 使用

  • https://github.com/HessTina-YuI/yui-old-blog

# 1. 初始化包(家里部分网络这种方式不行)

  1. npm install -g create-next-app
  2. npx create-next-app next-create

# npm init 的方式

https://blog.csdn.net/weixin_34326429/article/details/88010026

# 2. 别名引入

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/comp/*": ["components/*"],
      "@/pages/*": ["pages/*"],
    }
  }
}

//使用 @/comp/xxx

# 3. 同时请求多个数据

export async function getServerSideProps(context) {
  const [operationsRes, incidentsRes] = await Promise.all([
    fetch(`http://jsonplaceholder.typicode.com/users`),
    fetch(`http://jsonplaceholder.typicode.com/posts/1`)
  ])
  const [operations, incidents] = await Promise.all([
    operationsRes.json(),
    incidentsRes.json()
  ])
  return {
    props: {
      userList: operations,
      user: incidents
    }
  }
}

# 4. vscode 调试模式

  1. 创建一个以.vscode/launch.json 项目根目录命名的文件,内容如下:
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Next.js: debug server-side",
      "type": "node-terminal",
      "request": "launch",
      "command": "npm run dev"
    },
    {
      "name": "Next.js: debug client-side",
      "type": "pwa-chrome",
      "request": "launch",
      "url": "http://localhost:2009"  //package.json的端口号
    },
    {
      "name": "Next.js: debug full stack",
      "type": "node-terminal",
      "request": "launch",
      "command": "npm run dev",
      "console": "integratedTerminal",
      "serverReadyAction": {
        "pattern": "started server on .+, url: (https?://.+)",
        "uriFormat": "%s",
        "action": "debugWithChrome"
      }
    }
  ]
}

# 5. 请求说明

// 1. 请求自动携带cookie,在api文件夹获取即可
useEffect(async () => {
  getTestList()
    .then(res => {
      setTitle(res.title)
    })
    .catch(err => {
      console.log(err) //在next中必须要,不然会直接弹窗提示整个页面报错
    })
}, [])

useEffect(async () => {
  /* id && fetch(`/api/my`) // 非ssr请求路径不能带上主机地址
    .then(res => res.json()).then(json => {
      setList(json.data)
      console.log(json.data,'222')
    }) */
  if (id) {
    //详情页必须要这个判断,不然会发送两次请求
    let obj = {
      name: '222'
    }
    const res = await fetch(`/api/my`, {
      method: 'POST',
      body: JSON.stringify(obj)
    })
    const json = await res.json()
    console.log('页面打印--', json)
  }
}, [id])

// 2. 获取服务器数据,如需校验token,需要发送请求携带
export async function getServerSideProps(context) {
  const { id } = context.query
  console.log('roomId:', id)
  let obj = {
    name: '222'
  }
  const res = await fetch(`http://localhost:2008/api/my`, {
    //ssr请求路径一定要带上主机地址 http://localhost:2008
    method: 'POST',
    body: JSON.stringify(obj)
  })
  const json = await res.json()

  console.log('页面打印--', json)

  // console.log('环境变量7:',process.env.NODE_ENV,)

  // 获取本地cookie信息
  console.log('context.headers.cookie:', context.req.headers?.cookie)
  return {
    props: {
      data: json
    }
  }
}

# 6. 配置简单的代理

https://github.com/vercel/next.js/blob/7.0.0-canary.8/examples/with-zones/package.json

# 7. _app.js 不能配置 antd 的国际化,如下错误示范

return (
  <Provider store={store}>
    <ConfigProvider locale={zh_CN}>
      {' '}
      //不能在这里配置这个
      <Component {...pageProps} />
    </ConfigProvider>
  </Provider>
)

# 8. 读取数据库

import React, { useEffect, useState } from 'react'
import { useRouter } from 'next/router'

export default function Detail() {
  const router = useRouter()
  const { id } = router.query

  const [list, setList] = useState([])

  useEffect(() => {
    id &&
      fetch(`/api/detail/${id}`)
        .then(res => res.json())
        .then(json => {
          setList(json.data)
        })
  }, [id])

  return (
    <div>
      {list.map((item, index) => {
        return (
          <li key={index} className="item">
            {item.pid}
          </li>
        )
      })}
    </div>
  )
}

# 9. 路由传参数

import Jspang from '../components/Jspang'
import React from 'react'
import { useRouter } from 'next/router'
export default function New ()  {
  const router = useRouter()

  function gotoNext(){
    console.log('进入这个方法')
    router.push('/my')
  }

  function gotoXiaojiejie() {
    // 路由钩子事件
    router.events.on('routeChangeComplete',(...args)=>{
      console.log('routeChangeComplete->路由结束变化,参数为:',...args)
    })

    router.push({
      pathname:'/my',
      query:{
        name:'井空'
      }
    })
  }
  return (
    <>
      这是一个新闻页面
      <Jspang onClick={gotoNext} text='跳转按钮'></Jspang>
      <div onClick={gotoXiaojiejie}>55555555555555555555</div>
    </>
  )
}
export default function Jspang(props){
  return (
    <>
    <button onClick={props.onClick}>{props.text}</button>
    </>
  )
}

# 10. 路由跳转

// 官方写法
// import Link from 'next/link'
// import { useRouter } from 'next/router'

// export default function My() {
//   const router = useRouter()
//   return (
//     <>
//       <div>欢迎来到我的页面</div>
//       <Link href="/"><a>返回首页</a></Link>
//       <div>取到new的页面的值:{router.query.name}</div>

//       <button type="button" onClick={() => router.back()}>
//         Click here to go back
//       </button>
//     </>
//   )
// }

import { withRouter } from 'next/router'
import Link from 'next/link'

const My = ({ router }) => {
  console.log(router, 'router')
  return (
    <>
      <div>{router.query.name},来为我们服务了 .</div>
      <Link href="/">
        <a>返回首页</a>
      </Link>
    </>
  )
}
export default withRouter(My)
上次更新: