英文:
Radio buttons & Next JS
问题
以下是您提供的代码部分的翻译:
为了暴露我在一个Next JS应用程序中遇到的问题,我创建了以下测试应用程序,我称之为*radio-flash-test*。
以下是我用来创建应用程序的命令:
% npx create-next-app@latest
.....
% cd radio-flash-test
% heroku create radio-flash-test
以下是源代码的文件内容:
文件**app/page.tsx**:
```jsx
import Image from 'next/image'
import RadioDisplayMng from './components/RadioDisplayMng'
export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div className="z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex">
<RadioDisplayMng />
</div>
</main>
)
}
文件app/components/RadioDisplayMng.tsx:
'use client'
import React, { useEffect, useState } from "react";
import RadioChoice from "./RadioChoice";
import "./RadioDisplayMng.css";
import Flash from "./Flash";
export default function SentenceDisplayMng() {
const [choiceType, setChoiceType] = useState(1);
const [typeChecks, setTypeChecks] = useState([true, false, false]);
useEffect(() => {
switch (choiceType) {
case 1:
setTypeChecks([true, false, false]);
break;
case 2:
setTypeChecks([false, true, false]);
break;
case 3:
setTypeChecks([false, false, true]);
break;
default:
console.log('Unexpected case in useEffect=' + choiceType);
break;
}
}, [choiceType]);
return <div>
<FlashBox checks={typeChecks} />
<RadioChoice
actionFunc={(v) => setChoiceType(v)}
radChecks={typeChecks} />
</div>
} /* End of SentenceDisplayMng */
function FlashBox({ checks }: { checks: boolean[] }) {
return <div className="flasBx">
<Flash color={checks[0] ? "red" : "grey"} />
<Flash color={checks[1] ? "green" : "grey"} />
<Flash color={checks[2] ? "blue" : "grey"} />
</div>
} /* End of FlashBox */
文件app/components/RadioChoice.tsx:
import React, { useState, ChangeEvent } from "react";
import "./RadioChoice.css";
export default function RadioChoice(
{ radChecks, actionFunc = () => { } }:
{
radChecks: boolean[]
actionFunc?: (v: number) => void
}) {
function radioSelect(evt: ChangeEvent<HTMLInputElement>) {
console.log('radioSelect -> ' + evt.target.value);
if (typeof actionFunc === undefined) return;
actionFunc(parseInt(evt.target.value));
console.log('actionFunc called!');
} /* End of radioSelect */
return (
<div className='xrcTpSlctBlk'>
<label className='xrcTpLbl'>
从以下选项中选择
</label>
<div className='xrcTpRdbnBlk'>
<div className='rdbBlk'>
<div className='rdbtn'>
<input type='radio' name='exoTp' value={1}
checked={radChecks[0]}
onChange={e => radioSelect(e)} />
</div>
<div className='trsTpLbl'>Choice One</div>
</div>
<div className='rdbBlk'>
<div className='rdbtn'>
<input type='radio' name='exoTp' value={2}
checked={radChecks[1]}
onChange={e => radioSelect(e)} />
</div>
<div className='trsTpLbl'>Choice Two</div>
</div>
<div className='rdbBlk'>
<div className='rdbtn'>
<input type='radio' name='exoTp' value={3}
checked={radChecks[2]}
onChange={e => radioSelect(e)} />
</div>
<div className='trsTpLbl'>Choice Three</div>
</div>
</div>
</div>
)
}
文件app/components/Flash.tsx:
import "./Flash.css";
export default function Flash({ color }: { color: string }) {
let colrDsk = 'grey';
if (color === 'red') colrDsk = 'red';
else if (color === 'green') colrDsk = 'green';
else if (color === 'blue') colrDsk = 'blue';
const dskCls = "flasDisc " + colrDsk;
return (<div className={dskCls}></div>)
} /* End of Flash */
此应用程序在顶部显示三个灯:红色、绿色和蓝色,可以使用三个单选按钮打开和关闭这些灯。单击第一个按钮应该点亮红色,第二个按钮点亮绿色,第三个按钮点亮蓝色。
最后,您可以在此处查看并尝试应用程序:
https://radio-flash-test-6a054408fa42.herokuapp.com/
当尝试它时,您会注意到有时它不如预期地工作。我希望有第二双眼睛来查看并查找代码中的错误。非常感谢任何相关的提示。
请注意,我已将代码段的翻译提供给您,不包括代码注释或描述性文本。如果您需要进一步的翻译或有其他问题,请随时告诉我。
<details>
<summary>英文:</summary>
In order to expose one issue I am facing in a Next JS app, I created the following test app that I called *radio-flash-test*.
Here are the commands I used to create the app:
% npx create-next-app@latest
.....
% cd radio-flash-test
% heroku create radio-flash-test
These are the file contents for the source code:
File **app/page.tsx** :
import Image from 'next/image'
import RadioDisplayMng from './components/RadioDisplayMng'
export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div className="z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex">
<RadioDisplayMng />
</div>
</main>
)
}
File **app/components/RadioDisplayMng.tsx** :
'use client'
import React, {useEffect,useState} from "react";
import RadioChoice from "./RadioChoice";
import "./RadioDisplayMng.css";
import Flash from "./Flash";
export default function SentenceDisplayMng() {
const [choiceType, setChoiceType] = useState(1)
const [typeChecks, setTypeChecks] = useState([true,false, false])
useEffect(() => {
switch (choiceType) {
case 1:
setTypeChecks([true,false,false])
break;
case 2:
setTypeChecks([false,true,false])
break;
case 3:
setTypeChecks([false,false,true])
break;
default:
console.log('Unexpected case in useEffect=' +choiceType)
break;
}
}, [choiceType])
return <div>
<FlashBox checks={typeChecks} />
<RadioChoice
actionFunc={(v) => setChoiceType(v)}
radChecks={typeChecks} />
</div>
} /* End of SentenceDisplayMng */
function FlashBox({checks}:{checks: boolean[]}) {
return <div className="flasBx">
<Flash color={checks[0]?"red":"grey"} />
<Flash color={checks[1]?"green":"grey"} />
<Flash color={checks[2]?"blue":"grey"} />
</div>
} /* End of FlashBox */
File **app/components/RadioChoice.tsx** :
import React, {useState,ChangeEvent} from "react";
import "./RadioChoice.css";
export default function RadioChoice(
{radChecks,actionFunc=()=>{}}:
{
radChecks: boolean[]
actionFunc?: (v:number) => void
}) {
function radioSelect(evt:ChangeEvent<HTMLInputElement>) {
console.log('radioSelect -> '+evt.target.value)
if (typeof actionFunc===undefined) return
actionFunc(parseInt(evt.target.value))
console.log('actionFunc called!')
} /* End of radioSelect */
return (
<div className='xrcTpSlctBlk'>
<label className='xrcTpLbl'>
Choose among the following
</label>
<div className='xrcTpRdbnBlk'>
<div className='rdbBlk'>
<div className='rdbtn'>
<input type='radio' name='exoTp' value= {1}
checked={radChecks[0]}
onChange={e=>radioSelect(e)} />
</div>
<div className='trsTpLbl'>Choice One</div>
</div>
<div className='rdbBlk'>
<div className='rdbtn'>
<input type='radio' name='exoTp' value= {2}
checked={radChecks[1]}
onChange={e=>radioSelect(e)} />
</div>
<div className='trsTpLbl'>Choice Two</div>
</div>
<div className='rdbBlk'>
<div className='rdbtn'>
<input type='radio' name='exoTp' value= {3}
checked={radChecks[2]}
onChange={e=>radioSelect(e)} />
</div>
<div className='trsTpLbl'>Choice Three</div>
</div>
</div>
</div>
)
}
File **app/components/Flash.tsx** :
import "./Flash.css";
export default function Flash({color}:{color: string}) {
let colrDsk = 'grey'
if (color=='red') colrDsk = 'red'
else if (color=='green') colrDsk = 'green'
else if (color=='blue') colrDsk = 'blue'
const dskCls = "flasDisc "+colrDsk
return (<div className={dskCls}></div>)
} /* End of Flash */
The app displays three lights at the top; red, green and blue, which can be switched on and off using three radio buttons. Clicking on the first one should set light on the red, the second on the green and the third on the blue.
Finaly the app can be seen and tried out here:
https://radio-flash-test-6a054408fa42.herokuapp.com/
When one tries it, one will notice that it sometimes stops working as expected.
I would like to have a second pair of eyes take a look and see if a mistake can be spotted out inside the code. Many thanks for any relevant tip.
[![enter image description here][1]][1]
In case this could be useful, here is the contents of the **package.json** file :
{
"name": "radio-flash-test",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@types/node": "20.4.4",
"@types/react": "18.2.15",
"@types/react-dom": "18.2.7",
"autoprefixer": "10.4.14",
"eslint": "8.45.0",
"eslint-config-next": "13.4.12",
"next": "13.4.12",
"postcss": "8.4.27",
"react": "18.2.0",
"react-dom": "18.2.0",
"tailwindcss": "3.3.3",
"typescript": "5.1.6"
}
}
[1]: https://i.stack.imgur.com/soSH1.png
</details>
# 答案1
**得分**: 1
如果我从单选输入中移除'name'属性,它就能正常工作。似乎' onchange'事件没有触发,但不确定原因。
<details>
<summary>英文:</summary>
It works if I remove name prop from radio input. Seems like onchange event doesn't fire but not sure why
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论