You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React遍历Social对象切换通知图标并更新表单的问题

解决方案

核心问题是图标切换逻辑未与react-hook-form的表单状态联动,要么用了独立本地state,要么仅做日志输出未真正更新表单值。以下是可行修改方案:

1. 调整UserProfile组件,传递表单更新方法

将表单的setValue方法和实时的社交数据传给Tabledata组件,让子组件能直接操作表单状态:

export default function UserProfile(props) {
    const form = useForm({
        initialValues: {
            name: props.userProfile.name,
            socials: {
                email: {        
                    notifications: true,
                },
                facebook: {
                    notifications: false,
                },
                twitter: {
                    notifications: false,
                },
            },
        },
    });

    const handleSubmit = (data) => {
        console.log("提交数据:", data);
        // 这里写入提交逻辑,比如调用后端API
    };

    return (
        <> 
            <form
                method="post"
                className="pt-5"
                key={props.userProfile.id}
                onSubmit={form.onSubmit(handleSubmit)}
            >
                <TextInput
                    label="Name"
                    placeholder={props.userProfile.name}
                    {...form.getInputProps("name")}
                />
                <Tabledata
                    socials={form.watch("socials")}
                    updateNotification={form.setValue}
                />
                <button type="submit">Save</button>
            </form>
        </>
    )             
}

2. 重写Tabledata组件,实现图标切换与表单同步

移除独立本地状态,完全依赖表单状态渲染图标,点击时直接更新对应表单字段:

function Tabledata({ socials, updateNotification }) {
    const toggleStatus = (socialKey) => {
        const currentStatus = socials[socialKey].notifications;
        // 更新react-hook-form中的嵌套字段
        updateNotification(`socials.${socialKey}.notifications`, !currentStatus);
    };

    return (
        <>
            <Table>
                <thead>
                    <tr>
                        <th>Social channel</th>
                        <th>Notifications</th>
                    </tr>
                </thead>
                <tbody>
                    {Object.keys(socials).map((socialKey) => (
                        <tr key={socialKey}>
                            <td>{socialKey}</td>
                            <td>
                                {socials[socialKey].notifications ? (
                                    <CheckCircleIcon
                                        className="h-6 w-6 text-green-500 cursor-pointer"
                                        onClick={() => toggleStatus(socialKey)}
                                    />
                                ) : (
                                    <XCircleIcon
                                        className="h-6 w-6 text-red-500 cursor-pointer"
                                        onClick={() => toggleStatus(socialKey)}
                                    />
                                )}
                            </td>
                        </tr>
                    ))}
                </tbody>
            </Table>
        </>
    );
}

关键修改说明

  • 用form.watch("socials")获取实时表单社交数据,确保子组件拿到最新状态
  • 传递form.setValue给子组件,支持直接更新嵌套的表单字段
  • 移除子组件本地useState,完全依赖表单状态渲染,保证状态同步
  • 给图标添加cursor-pointer类,明确可点击交互性
  • 点击图标时,通过路径socials.{socialKey}.notifications精准更新对应布尔值

修改后点击图标即可实时切换通知状态,表单值会同步更新,提交时能拿到最新状态。

内容的提问来源于stack exchange,提问作者Somdotta Sarkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 17:40:29