已选中单选按钮 属性 未从列表中的按钮调用
Radio button checked property not called from Button in a List
我想编写一个 React 组件,向用户显示他们可以使用 Semantic UI 中的单选按钮接受或拒绝的提案列表。
我的应用看起来像这样。
import React from "react";
import "./App.css";
import {Proposals} from "./components/Proposals";
function App() {
const proposals = [
{id: "1", context: "The cat is happy."},
{id: "2", context: "The triangle is blue."}
];
return (
<div>
<Proposals proposals={proposals}/>
</div>
)
}
export default App;
我的提案组件如下所示。
import React, {useState} from "react"
import {Form, Header, List, Radio} from "semantic-ui-react";
export const Proposals = ({proposals}) => {
const [judgments, setJudgments] = useState(
proposals.reduce((result, proposal) => {
result[proposal.id] = {accept: false, reject: false};
return result;
}, {})
);
const judge = (id) => {
return function (e, {value}) {
judgments[id].accept = value === "accept";
judgments[id].reject = value === "reject";
setJudgments(judgments)
};
};
return (
<div id="proposals">
<Header>Proposals</Header>
<List>
{proposals.map(proposal => {
return (
<List.Item key={proposal.id}>
<div>{proposal.context}</div>
<Form>
<Form.Group inline>
<Radio label="Accept"
value="accept"
name="accept-reject"
checked={judgments[proposal.id].accept}
onChange={judge(proposal.id)}/>
<Radio label="Reject"
value="reject"
name="accept-reject"
checked={judgments[proposal.id].reject}
onChange={judge(proposal.id)}/>
</Form.Group>
</Form>
</List.Item>
)
}
)}
</List>
</div>
)
};
我正在做的棘手的事情是将我的 onChange
处理程序 judge
写成一个闭包,这样我就可以传入正在操作的提案的 ID。这行得通。当我点击一个单选按钮时,judge
函数被调用,如果我将它的值记录到控制台,它们看起来都是正确的。
但是,当我单击它们时,单选按钮的状态并没有改变。如果我让 checked
属性 调用一个也记录到控制台的函数,我看到它只在应用程序加载时被调用一次,再也不会被调用。
我将 与单个无线电组一起使用,效果很好。大概列表中的单选按钮有些东西搞砸了,但我不知道那是什么。
根据下面答案的建议,我将 judge
函数更改为以下内容。
const judge = (id) => {
return function (e, {value}) {
setJudgments(prev => {
if (prev.id !== id) return prev;
return {
...prev,
accept: value === "accept",
reject: value === "reject"
}
})
}
};
我也遇到了同样的问题
虽然这似乎与我的不当updating state有关。
judge
上的闭包没有任何问题。你的问题是你正在改变 state
judgments[id].accept = value === "accept"
您应该使用 useState
setter 的更新版本来设置您的状态。
像这样
return function (e, {value}) {
setJudgments(prev =>({
...prev,
[id] :{
...prev[id],
accept: value === "accept",
reject: value === "reject"
}
}))
};
我想编写一个 React 组件,向用户显示他们可以使用 Semantic UI 中的单选按钮接受或拒绝的提案列表。
我的应用看起来像这样。
import React from "react";
import "./App.css";
import {Proposals} from "./components/Proposals";
function App() {
const proposals = [
{id: "1", context: "The cat is happy."},
{id: "2", context: "The triangle is blue."}
];
return (
<div>
<Proposals proposals={proposals}/>
</div>
)
}
export default App;
我的提案组件如下所示。
import React, {useState} from "react"
import {Form, Header, List, Radio} from "semantic-ui-react";
export const Proposals = ({proposals}) => {
const [judgments, setJudgments] = useState(
proposals.reduce((result, proposal) => {
result[proposal.id] = {accept: false, reject: false};
return result;
}, {})
);
const judge = (id) => {
return function (e, {value}) {
judgments[id].accept = value === "accept";
judgments[id].reject = value === "reject";
setJudgments(judgments)
};
};
return (
<div id="proposals">
<Header>Proposals</Header>
<List>
{proposals.map(proposal => {
return (
<List.Item key={proposal.id}>
<div>{proposal.context}</div>
<Form>
<Form.Group inline>
<Radio label="Accept"
value="accept"
name="accept-reject"
checked={judgments[proposal.id].accept}
onChange={judge(proposal.id)}/>
<Radio label="Reject"
value="reject"
name="accept-reject"
checked={judgments[proposal.id].reject}
onChange={judge(proposal.id)}/>
</Form.Group>
</Form>
</List.Item>
)
}
)}
</List>
</div>
)
};
我正在做的棘手的事情是将我的 onChange
处理程序 judge
写成一个闭包,这样我就可以传入正在操作的提案的 ID。这行得通。当我点击一个单选按钮时,judge
函数被调用,如果我将它的值记录到控制台,它们看起来都是正确的。
但是,当我单击它们时,单选按钮的状态并没有改变。如果我让 checked
属性 调用一个也记录到控制台的函数,我看到它只在应用程序加载时被调用一次,再也不会被调用。
我将
根据下面答案的建议,我将 judge
函数更改为以下内容。
const judge = (id) => {
return function (e, {value}) {
setJudgments(prev => {
if (prev.id !== id) return prev;
return {
...prev,
accept: value === "accept",
reject: value === "reject"
}
})
}
};
我也遇到了同样的问题
虽然这似乎与我的不当updating state有关。
judge
上的闭包没有任何问题。你的问题是你正在改变 state
judgments[id].accept = value === "accept"
您应该使用 useState
setter 的更新版本来设置您的状态。
像这样
return function (e, {value}) {
setJudgments(prev =>({
...prev,
[id] :{
...prev[id],
accept: value === "accept",
reject: value === "reject"
}
}))
};