nextjsでエラー出た。
‘React’ は UMD グローバルを参照していますが、現在のファイルはモジュールです。代わりにインポートを追加することを考慮してください。ts(2686)
import React from ‘react’;
上記を追加したら直りました。あと、最後にセミコロンを付けたほうがいいとAIに言われました。
よかった。
nextjsでエラー出た。
‘React’ は UMD グローバルを参照していますが、現在のファイルはモジュールです。代わりにインポートを追加することを考慮してください。ts(2686)
import React from ‘react’;
上記を追加したら直りました。あと、最後にセミコロンを付けたほうがいいとAIに言われました。
よかった。
nextjsのインストール方法。
下記リンク先参照のこと。
https://qiita.com/asahina820/items/23838bb454097e73035c
https://zenn.dev/naoji/articles/nextjs-10minitues-installation-0010
確認方法
node -v, npm -v, npx -v
今日の時点では、
node v22.11.0, npm 10.9.0, npx 10.9.0
my-next-appフォルダに移動して、
npm run dev
で、起動。起動できたら、一段落終了。
【開発中のサイトから】
元のappフォルダを新規appフォルダにコピー。
元のpublicフォルダから新規publicフォルダにsvg画像をコピー。
自分用のメモです。
10.配列の要素をランダムに並び替える関数。
//配列の要素をランダムに並び替える関数。arrayには数字が入った配列が入る。戻り値はランダムにした配列。
const shufflesArray = (array: (number | undefined)[]): (number | undefined)[] => {
//配列のコピー
const cloneArray = [...array]
//配列をランダムにシャッフル
const shuffled = cloneArray.sort(() => 0.5 - Math.random());
//console.log(shuffled);
return shuffled;
}
11.配列の要素から指定した要素を抜いて、ランダムに3つの要素を取り出す関数。
//正解1つ、間違い3つのランダムに4つの数字を選ぶ関数。戻り値は配列。
//arrayは配列が入る。countは間違いの個数が入る、3を指定。mは正解が入る。
const RandomSelected2 = (array: number[], count: number, m: number): (number | undefined)[] => {
//配列のコピー
const copyArrays = [...array];
//配列から正解だけを引く
const newArray = copyArrays.filter(copyArray => copyArray !== m);
//配列をランダムにシャッフル
const shuffled = newArray.sort(() => 0.5 - Math.random());
//配列の先頭から3つ選ぶ
const randomElements = shuffled.slice(0, count);
return randomElements;
}
12.Unhandled Runtime Errorの解決方法が分かった。
Error: Text content does not match server-rendered HTML. See more info here: https://nextjs.org/docs/messages/react-hydration-error
Text content did not match. Server: “47” Client: “10”
サーバー側とクライアント側のレンダリングにずれが発生したときに出るエラー。
const Page = () => {
const h1Title = "九九ゲーム"
const shinArray = [...Num99s5];
ShinFiveTables.map((Shin9) => {
//ランダムな数が入った3つの配列
const threeArray = RandomSelected2(shinArray, 3, Shin9.answer);
//ランダムな数が入った3つの配列に正解の数が入り4つの配列となる。
threeArray.unshift(Shin9.answer);
//4つの配列をシャッフルする
const shufflelist = shufflesArray(threeArray);
//4つの配列を一つずつコピーする。
Shin9.reply['rep1'] = shufflelist[0];
Shin9.reply['rep2'] = shufflelist[1];
Shin9.reply['rep3'] = shufflelist[2];
Shin9.reply['rep4'] = shufflelist[3];
})
return (
<>
<div className="container m-auto">
<main className="flex flex-col items-center justify-between p-24">
<div className='flex-initial w-1600 bg-blue-100'>
<h1 className="my-4 text-center font-bold text-5xl tracking-tight bg-gradient-to-r from-green-500 via-blue-500 to-pink-500 bg-clip-text text-transparent">{h1Title}</h1>
</div>
</main>
<main className="flex flex-col items-center justify-between p-24">
<OneQuestionAndAnswer3 ShinFiveTables={ShinFiveTables}/>
</main>
<main className="flex flex-col items-center justify-between p-24">
<p><Link href="/" className="text-2xl font-bold text-red-600">Home</Link></p>
<p><Link href="/sub1" className="text-2xl font-bold text-red-600">sub1</Link></p>
<p><Link href="/sub2" className="text-2xl font-bold text-red-600">九九ゲーム</Link></p>
</main>
</div>
</>
)
}
export default dynamic(async () => Page, { ssr: false });
export default dynamic(async () => Page, { ssr: false });
https://zenn.dev/sora_kumo/articles/7f8a86c005f850
asyncを入れることによって、エラーが回避されました。よかった。
自分用のメモです。
8.間違いがクリックされても4択の数字が更新され、仕様どおりにならなかった。
export const OneQuestionAndAnswer2 = () => {
const [ques_num, ques_numSet] = useState(0);
const [ques_boolean, ques_booleanSet] = useState('');
return (
<>
<p className="text-2xl font-bold text-600">{ques_num + 1} 問目</p>
<div className="FiveTables">
<p className="text-2xl font-bold text-blue-600">No {FiveTables[ques_num].id} : {FiveTables[ques_num].num1} × {FiveTables[ques_num].num2} = </p>
<main className="grid grid-cols-4 justify-items-stretch gap-[5px] m-5">
<FourAnswer_b array_a={Num99s5} num_a={3} num_b={FiveTables[ques_num].answer} ques_num={ques_num} ques_numSet={ques_numSet} ques_booleanSet={ques_booleanSet} />
</main>
</div>
<p className="text-2xl font-bold text-red-600">{ques_boolean}</p>
</>
);
}
//array_aは配列、Num99s5配列が入る。num_aは間違いの個数が入る、3が指定されている。num_bは正解が入る。
const FourAnswer_b = (props:any) => {
const list = RandomSelected(props.array_a, props.num_a, props.num_b);
list.push(props.num_b);
const shufflelist = shufflesArray(list);
const handleClick4 = (OneTable:any) => {
if(OneTable === props.num_b){
if(props.ques_num < 8){
console.log('正解。' + OneTable + 'がクリックされ、正解は' + props.num_b + 'でした');
props.ques_numSet(props.ques_num + 1);
props.ques_booleanSet('正解。' + OneTable + 'がクリックされました。');
} else {
console.log('正解。' + OneTable + 'がクリックされ、正解は' + props.num_b + 'でした。おしまい');
props.ques_booleanSet('正解。' + OneTable + 'がクリックされました。おしまい');
}
} else {
console.log('間違い。' + OneTable + 'がクリックされました')
props.ques_booleanSet('間違い。' + OneTable + 'がクリックされました');
}
};
return (
<>
{shufflelist.map((OneTable) => {
return (
<button onClick={() => handleClick4(OneTable)}><div className="bg-red-100 p-5">{OneTable}</div></button>
);
})}
</>
);
};
9.正解した時だけ、4択も更新されるようになった。想定された仕様どおりになったが、Unhandled Runtime Errorが出る問題が直らない。
export const OneQuestionAndAnswer3 = (props:any) => {
const [ques_num, ques_numSet] = useState(0);
const [ques_boolean, ques_booleanSet] = useState('');
const handleClick4 = (OneTable:any) => {
if (OneTable === props.ShinFiveTables[ques_num].answer){
if (props.ShinFiveTables[ques_num].id < 9){
ques_booleanSet('正解。' + OneTable + 'がクリックされました。');
ques_numSet(ques_num + 1);
} else {
ques_booleanSet('正解。' + OneTable + 'がクリックされました。おしまい');
}
} else {
ques_booleanSet('間違い。' + OneTable + 'がクリックされました。');
}
};
return (
<>
<p className="text-2xl font-bold text-600 mb-8">{props.ShinFiveTables[ques_num].id} 問目</p>
<p className="text-2xl font-bold text-blue-600">{props.ShinFiveTables[ques_num].num1} × {props.ShinFiveTables[ques_num].num2} = </p>
<div className="FiveTables">
<main className="grid grid-cols-4 justify-items-stretch gap-[5px] m-5">
<button onClick={() => handleClick4(props.ShinFiveTables[ques_num].reply.rep1)}><div className="bg-red-100 p-5">{props.ShinFiveTables[ques_num].reply.rep1}</div></button>
<button onClick={() => handleClick4(props.ShinFiveTables[ques_num].reply.rep2)}><div className="bg-red-100 p-5">{props.ShinFiveTables[ques_num].reply.rep2}</div></button>
<button onClick={() => handleClick4(props.ShinFiveTables[ques_num].reply.rep3)}><div className="bg-red-100 p-5">{props.ShinFiveTables[ques_num].reply.rep3}</div></button>
<button onClick={() => handleClick4(props.ShinFiveTables[ques_num].reply.rep4)}><div className="bg-red-100 p-5">{props.ShinFiveTables[ques_num].reply.rep4}</div></button>
</main>
</div>
<p className="text-2xl font-bold text-red-600">{ques_boolean}</p>
</>
);
}
6.useStateを再レンダリングしても親要素と子要素では更新される範囲が違うことが分かった。
//親要素
export default function Page() {
const h1Title = "九九ゲーム"
const [fisrtNumber, setNumber] = useState(0);
return (
<>
<div className="container m-auto">
<main className="flex flex-col items-center justify-between p-24">
<div className='flex-initial w-1600 bg-blue-100'>
<h1 className="my-4 text-center font-bold text-5xl tracking-tight bg-gradient-to-r from-green-500 via-blue-500 to-pink-500 bg-clip-text text-transparent">{h1Title}</h1>
</div>
</main>
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<ClientComponent2 />
<p>掛け算5の段ノーマルFourTablesApp</p>
<FourTablesApp />
<p>掛け算5の段ノーマルの問題と4つの回答</p>
<FourTablesAndAnswer />
<button onClick={() => console.log('bbb.tsx が押下されました')}>Click me</button>
<button onClick={() => console.log('Hello, Client')}>Hello, Client</button>
<p>Increaseボタンを{fisrtNumber}回クリック</p>
<button onClick={() => setNumber(fisrtNumber + 1)}>Increase</button>
<p>掛け算5の段ノーマルの問題と4つの回答を一つずつ</p>
<OneQuestionAndAnswer />
<OneQuestionAndAnswer2 />
</main>
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<p><Link href="/" className="text-2xl font-bold text-red-600">Home</Link></p>
<p><Link href="/sub1" className="text-2xl font-bold text-red-600">sub1</Link></p>
<p><Link href="/sub2" className="text-2xl font-bold text-red-600">九九ゲーム</Link></p>
</main>
</div>
</>
)
}
//子要素
export const OneQuestionAndAnswer2 = () => {
const [ques_num, ques_numSet] = useState(0);
return (
<>
<p>Child4カウント:{ques_num}</p>
<div className="FiveTables">
<p>No {FiveTables[ques_num].id} : {FiveTables[ques_num].num1} × {FiveTables[ques_num].num2} = {FiveTables[ques_num].answer}</p>
<main className="grid grid-cols-4 justify-items-stretch gap-[5px] m-5">
<FourAnswer_b array_a={Num99s5} num_a={3} num_b={FiveTables[ques_num].answer} ques_num={ques_num} ques_numSet={ques_numSet}/>
</main>
</div>
</>
);
}
//array_aは配列、Num99s5配列が入る。num_aは間違いの個数が入る、3が指定されている。num_bは正解が入る。
const FourAnswer_b = (props) => {
const list = RandomSelected(props.array_a, props.num_a, props.num_b);
list.push(props.num_b);
const shufflelist = shufflesArray(list);
const handleClick4 = (OneTable) => {
if(OneTable === props.num_b){
console.log('正解。' + OneTable + 'がクリックされ、正解は' + props.num_b + 'でした');
props.ques_numSet(props.ques_num + 1);
} else {
console.log('間違い。' + OneTable + 'がクリックされ、正解は' + props.num_b + 'でした')
}
};
return (
<>
{shufflelist.map((OneTable) => {
return (
<button onClick={() => handleClick4(OneTable)}><div className="bg-red-100 p-5">{OneTable}</div></button>
);
})}
</>
);
};
7.useStateの書き方に何種類かあること、引数の順番は逆でもよいことが分かった。
export const Parent = () => {
const [text, setText] = useState('');
const [count1, setCount] = useState(123);
// ↑親コンポーネントで使う:textの初期値とtextを更新する関数を宣言
// ↓子コンポーネントから受け取った値で親コンポーネントのtextを更新する関数A
const handleValueChange = (newValue2:any) => {
setText(newValue2);
};
// ↓子コンポーネントから受け取った値で親コンポーネントのtextを更新する関数A
const handleValueChange3 = (newValue:any) => {
setCount(newValue + 1);
};
const [count4, setCount4] = useState(0);
const [count5, setCount5] = useState(0);
const [count6, setCount6] = useState(0);
return (
<>
<p>ああああああああああああ</p>
<div>
<Child2 handleValueChange={handleValueChange} />
</div>
<div>
<Child3 count={count1} />
<ButtonComponent handleValueChange3={handleValueChange3}/>
</div>
<div>
<p>Child4カウント:{count4}</p>
<Child4 count={count4} setCount={setCount4} />
</div>
<div>
<p>Child5カウント:{count5}</p>
<Child5 count={count5} setCount={setCount5} />
</div>
<div>
<p>Child6カウント:{count6}</p>
<Child6 count={count6} setCount={setCount6} />
</div>
</>
);
};
export const Child4 = (props:any)=>{
// 引数でpropsを受け取る
const handleClick4 = () => {
props.setCount(props.count + 1);
};
return(
<>
<button onClick = {handleClick4}>カウントアップ</button>
</>
);
};
export const Child5 = ({setCount,count})=>{
// 引数で{count, setCount}を受け取る
const handleClick5 = () => {
setCount(count + 1);
};
return(
<>
<button onClick = {handleClick5}>Child5カウントアップ</button>
</>
);
};
export const Child6 = ({count, setCount})=>{
// 引数で{setCount,count}逆の順番で受け取る
const handleClick6 = () => {
setCount(count + 1);
};
return(
<>
<button onClick = {() => {handleClick6()}}>Child6カウントアップ</button>
</>
);
};