//tips
//smart contract
IndexにLinkを組み込んで[id].jsへリンクさせるところから確認。
{notes&&(
<div>
{notes.map(note => (
<Link>
<div href={'/ID/'+note.id} key={note.id} >
<a><h3>{note.title}</h3></a>
</div>
</Link>
))}
</div>
)}
一旦このような形でリンクを作成し、[id].jsに飛ばそうとしたがエラー。
Error: Failed prop type: The prop `href` expects a `string` or `object` in `<Link>`, but got `undefined` instead.
Hrefの位置がおかしかったのでリンクの中に入れたら無事に反映でき、noteのタイトルを押すと[id].jsの各ページに飛ぶことができた。
{notes&&(
<div>
{notes.map(note => (
<Link href={'/ID/'+ note.id} key={note.id}>
<div >
<a><h3>{note.title}</h3></a>
</div>
</Link>
))}
</div>
)}
次にテキストフィールドに記入したid数値を読み取り、遷移させる。ここではrouter.pushを使用している。
ID LINK
<form noValidate autoComplete="off" onSubmit={handleOnLINK}>
<TextField
onChange={(e)=>setID(e.target.value)}
//className={classes.field}
//label="Note Title"
variant="outlined"
color="secondary"
fullWidth
required
//error={titleError}
/>
<Box textAlign="center">
<Button
type="submit"
varient="contained"
>
submit
</Button>
</Box>
</form>
const handleOnLINK = (e) => {
e.preventDefault()
router.push('/ID/'+ myidlink)
}
こちらに0xa242fcb2acbb118ea1b6829efe8b7e2087b00000を入力してもきちんと作用した。
http://localhost:3000/ID/0xa242fcb2acbb118ea1b6829efe8b7e2087b00000
これらの各idの特徴をページに反映していくためにはidと特徴が紐づけられたデータベースが必要。
ここではjson placeholderを使用していく。
https://jsonplaceholder.typicode.com/users
ここからデータをfetchして持ってくる。
これはjsonserver上に自分で自作したものをfetchしても良い。
下記の形態を使用でサンプルの取得を確認できた。 getStaticProps = async () => {を使うことでconst Ninjasが実行される前にfetchし情報を取り込んでおいてくれる。その取り込んだ情報をpropsとして渡している。
import styles from '../../styles/Ninjas.module.css'
export const getStaticProps = async () => {
const res = await fetch('https://jsonplaceholder.typicode.com/users');
const data = await res.json();
return {
props: { ninjas: data }
}
}
const Ninjas = ({ ninjas }) => {
console.log(ninjas)
return (
<div>
<h1>All Ninjas</h1>
{ninjas.map(ninja => (
<div key={ninja.id}>
<a className={styles.single}>
<h3>{ ninja.name }</h3>
</a>
</div>
))}
</div>
);
}
export default Ninjas;
さらにこのようなページから実際の[id].jsページに飛ぶ際には、getStaticPathsの使用が推奨されており、動的ルーティングをしているページをPre-renderingして静的コンテンツにできる。
pathsキーは、どのパスをPre-renderingするかを指定。
fallbackキーとは、指定されたパスをtrue、falseのどちらで返すかを決めるもので、fallback:falseの際には、getStaticPathsで生成されていないパスは全て404ページを返す。fallback:trueの際には、返されるのは事前に生成されたHTMLとなる。
参考:
https://qiita.com/matamatanot/items/1735984f40540b8bdf91
[id].jsを下記のように加工することで取得したjson情報を個別ページの内容として反映させることができた。
//受け取るcontextの内容を編集
export const getStaticPaths = async () => {
const res = await fetch('https://jsonplaceholder.typicode.com/users');
const data = await res.json();
// map data to an array of path objects with params (id)
const paths = data.map(ninja => {
return {
params: { id: ninja.id.toString() }
}
})
console.log(paths)
// [
// { params: { id: '1' } },
// { params: { id: '2' } },
// { params: { id: '3' } },
// { params: { id: '4' } },
// { params: { id: '5' } },
// { params: { id: '6' } },
// { params: { id: '7' } },
// { params: { id: '8' } },
// { params: { id: '9' } },
// { params: { id: '10' } }
// ]
return {
paths,
fallback: false
}
}
//contextは{ params: { id: '2' },などの内容で取得
export const getStaticProps = async (context) => {
console.log(context)
// {
// params: { id: '2' },
// locales: undefined,
// locale: undefined,
// defaultLocale: undefined
// }
const id = context.params.id;
const res = await fetch('https://jsonplaceholder.typicode.com/users/' + id);
const data = await res.json();
return {
props: { ninja: data }
}
}
const Details = ({ ninja }) => {
return (
<div>
<h1>{ ninja.name }</h1>
<p>{ ninja.email }</p>
<p>{ ninja.website }</p>
<p>{ ninja.address.city }</p>
</div>
);
}
export default Details;