单选按钮和Next.js

huangapple go评论135阅读模式
英文:

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 &#39;next/image&#39;
import RadioDisplayMng from &#39;./components/RadioDisplayMng&#39;
export default function Home() {
return (
&lt;main className=&quot;flex min-h-screen flex-col items-center justify-between p-24&quot;&gt;
&lt;div className=&quot;z-10 w-full max-w-5xl items-center    justify-between font-mono text-sm lg:flex&quot;&gt;
&lt;RadioDisplayMng /&gt;
&lt;/div&gt;
&lt;/main&gt;
)
}
File **app/components/RadioDisplayMng.tsx** :
&#39;use client&#39;
import React, {useEffect,useState} from &quot;react&quot;;
import RadioChoice from &quot;./RadioChoice&quot;;
import &quot;./RadioDisplayMng.css&quot;;
import Flash from &quot;./Flash&quot;;
export default function SentenceDisplayMng() {
const [choiceType, setChoiceType] = useState(1)
const [typeChecks, setTypeChecks] = useState([true,false,   false])
useEffect(() =&gt; {
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(&#39;Unexpected case in useEffect=&#39; +choiceType)
break;
}
}, [choiceType])
return &lt;div&gt;
&lt;FlashBox checks={typeChecks} /&gt;
&lt;RadioChoice
actionFunc={(v) =&gt; setChoiceType(v)} 
radChecks={typeChecks} /&gt;
&lt;/div&gt;
} /* End of SentenceDisplayMng */
function FlashBox({checks}:{checks: boolean[]}) {
return &lt;div className=&quot;flasBx&quot;&gt;
&lt;Flash color={checks[0]?&quot;red&quot;:&quot;grey&quot;} /&gt;
&lt;Flash color={checks[1]?&quot;green&quot;:&quot;grey&quot;} /&gt;
&lt;Flash color={checks[2]?&quot;blue&quot;:&quot;grey&quot;} /&gt;
&lt;/div&gt;
} /* End of FlashBox */
File **app/components/RadioChoice.tsx** :
import React, {useState,ChangeEvent} from &quot;react&quot;;
import &quot;./RadioChoice.css&quot;;
export default function RadioChoice(
{radChecks,actionFunc=()=&gt;{}}:
{
radChecks: boolean[]
actionFunc?: (v:number) =&gt; void
}) {
function radioSelect(evt:ChangeEvent&lt;HTMLInputElement&gt;) {
console.log(&#39;radioSelect -&gt; &#39;+evt.target.value)
if (typeof actionFunc===undefined) return
actionFunc(parseInt(evt.target.value))
console.log(&#39;actionFunc called!&#39;)
} /* End of radioSelect */
return (
&lt;div className=&#39;xrcTpSlctBlk&#39;&gt;
&lt;label className=&#39;xrcTpLbl&#39;&gt;
Choose among the following
&lt;/label&gt;
&lt;div className=&#39;xrcTpRdbnBlk&#39;&gt;
&lt;div className=&#39;rdbBlk&#39;&gt;
&lt;div className=&#39;rdbtn&#39;&gt;
&lt;input type=&#39;radio&#39; name=&#39;exoTp&#39; value= {1}
checked={radChecks[0]}
onChange={e=&gt;radioSelect(e)} /&gt;
&lt;/div&gt;
&lt;div className=&#39;trsTpLbl&#39;&gt;Choice One&lt;/div&gt;
&lt;/div&gt;
&lt;div className=&#39;rdbBlk&#39;&gt;
&lt;div className=&#39;rdbtn&#39;&gt;
&lt;input type=&#39;radio&#39; name=&#39;exoTp&#39; value= {2}
checked={radChecks[1]}
onChange={e=&gt;radioSelect(e)} /&gt;
&lt;/div&gt;
&lt;div className=&#39;trsTpLbl&#39;&gt;Choice Two&lt;/div&gt;
&lt;/div&gt;
&lt;div className=&#39;rdbBlk&#39;&gt;
&lt;div className=&#39;rdbtn&#39;&gt;
&lt;input type=&#39;radio&#39; name=&#39;exoTp&#39; value= {3}
checked={radChecks[2]}
onChange={e=&gt;radioSelect(e)} /&gt;
&lt;/div&gt;
&lt;div className=&#39;trsTpLbl&#39;&gt;Choice Three&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
)
}
File **app/components/Flash.tsx** :
import &quot;./Flash.css&quot;;
export default function Flash({color}:{color: string}) {
let colrDsk = &#39;grey&#39;
if (color==&#39;red&#39;) colrDsk = &#39;red&#39;
else if (color==&#39;green&#39;) colrDsk = &#39;green&#39;
else if (color==&#39;blue&#39;) colrDsk = &#39;blue&#39;
const dskCls = &quot;flasDisc &quot;+colrDsk
return (&lt;div className={dskCls}&gt;&lt;/div&gt;)
} /* 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 :
{
&quot;name&quot;: &quot;radio-flash-test&quot;,
&quot;version&quot;: &quot;0.1.0&quot;,
&quot;private&quot;: true,
&quot;scripts&quot;: {
&quot;dev&quot;: &quot;next dev&quot;,
&quot;build&quot;: &quot;next build&quot;,
&quot;start&quot;: &quot;next start&quot;,
&quot;lint&quot;: &quot;next lint&quot;
},
&quot;dependencies&quot;: {
&quot;@types/node&quot;: &quot;20.4.4&quot;,
&quot;@types/react&quot;: &quot;18.2.15&quot;,
&quot;@types/react-dom&quot;: &quot;18.2.7&quot;,
&quot;autoprefixer&quot;: &quot;10.4.14&quot;,
&quot;eslint&quot;: &quot;8.45.0&quot;,
&quot;eslint-config-next&quot;: &quot;13.4.12&quot;,
&quot;next&quot;: &quot;13.4.12&quot;,
&quot;postcss&quot;: &quot;8.4.27&quot;,
&quot;react&quot;: &quot;18.2.0&quot;,
&quot;react-dom&quot;: &quot;18.2.0&quot;,
&quot;tailwindcss&quot;: &quot;3.3.3&quot;,
&quot;typescript&quot;: &quot;5.1.6&quot;
}
}
[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&#39;t fire but not sure why
</details>

huangapple
  • 本文由 发表于 2023年7月24日 14:52:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76752034.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定