【问题标题】:Radio button checked property not called from Button in a List未从列表中的按钮调用单选按钮检查属性
【发布时间】:2020-03-03 06:48:09
【问题描述】:

我想编写一个 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 属性调用一个也记录到控制台的函数,我会看到它只会在应用程序加载时被调用一次,而不会再次调用。

我将same pattern 与单个无线电组一起使用,它工作正常。大概有一些关于单选按钮在一个列表中的东西把事情搞砸了,但我不知道那是什么。


按照以下答案的建议,我将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 有关。

【问题讨论】:

    标签: javascript reactjs radio-button semantic-ui radio-group


    【解决方案1】:

    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"
             }
         }))
    };
    

    【讨论】:

    • 什么是prev?当我将上述函数设为judge 闭包返回的函数时,我收到错误“prev.map 不是函数”。如果我将prev 替换为judgments 也是一样。
    • prevjudgementssnapshot。我使用了map,因为我认为judgments 是一个数组,但它不对吗?是对象吗?
    • judgements 是一个对象。它看起来像这样{"1":{"accept":false,"reject":false},"2":{"accept":false,"reject":false}}。但请参阅我上面的编辑。
    • 更新答案
    • 差不多。这在对象更新中执行... [id]: { accept: value === "accept", reject: value === "reject" }
    猜你喜欢
    • 1970-01-01
    • 2019-05-29
    • 2021-08-14
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-16
    • 2019-05-08
    相关资源
    最近更新 更多