Chakra Editable组件失焦时无法触发提交的问题求助
问题:Chakra UI Editable组件提交事件无法触发
我尝试用Chakra的Editable组件实现卡片数据的可编辑功能,按官方文档将handleSubmit函数传入onSubmit属性后,本该向Ruby on Rails后端发送PATCH请求完成修改,但提交操作从未触发——按回车键或输入框失焦都没有调用onSubmit,submit函数里的console.log没有任何输出,也没有报错。试过添加submitOnBlur属性、通过状态调用提交、修改onSubmit写法等,要么没用要么导致组件渲染异常。
原代码
function DadDetails() { const { user, setUser } = useContext(UserContext); const [email, setEmail] = useState(user.email); const handleSubmit = (e) => { console.log(user); fetch(`/people/${user.id}`, { method: "PATCH", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ email: email }), }) .then((res) => res.json()) .then((data) => { setUser({ ...user, email: email }); }) .catch((error) => { console.error('Error:', error); }); }; return ( <Card borderRadius="30px"> <CardHeader> <Avatar /> <Flex flexDir="column" ml={4} mt={1}> <Heading fontSize="xl">{user.name}</Heading> </Flex> </CardHeader> <CardBody> <Stack divider={<StackDivider />} spacing="4"> <Box> <Heading size="xs" textTransform="uppercase"> Email </Heading> <Editable submitOnBlur={true} defaultValue={user.email} onSubmit={handleSubmit} onChange={(e)=> setEmail(e.target.value)} > <EditablePreview /> <EditableInput /> </Editable> </Box> <Box> <Heading size="xs" textTransform="uppercase"> Birthday </Heading> <Text pt="2" fontSize="sm"> {user.date_of_birth} </Text> </Box> <Box> <Heading size="xs" textTransform="uppercase"> Zip Code </Heading> <Text pt="2" fontSize="sm"> {user.zip_code} </Text> </Box> </Stack> </CardBody> </Card> ); } export default DadDetails;
问题原因与解决方案
核心问题是对Chakra Editable组件的回调参数格式理解有误:
- Editable的
onChange接收的是新的文本值,不是原生事件对象,原代码里的e.target.value会导致报错,进而阻塞后续逻辑 defaultValue仅初始化生效,后续编辑需要绑定value属性同步状态,否则输入和预览会不一致onSubmit接收的是提交的最终值,不是事件对象
修改后的代码
function DadDetails() { const { user, setUser } = useContext(UserContext); const [email, setEmail] = useState(user.email); const handleSubmit = (submittedValue) => { console.log(user); fetch(`/people/${user.id}`, { method: "PATCH", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ email: submittedValue }), }) .then((res) => res.json()) .then((data) => { setUser({ ...user, email: submittedValue }); }) .catch((error) => { console.error('Error:', error); }); }; return ( <Card borderRadius="30px"> <CardHeader> <Avatar /> <Flex flexDir="column" ml={4} mt={1}> <Heading fontSize="xl">{user.name}</Heading> </Flex> </CardHeader> <CardBody> <Stack divider={<StackDivider />} spacing="4"> <Box> <Heading size="xs" textTransform="uppercase"> Email </Heading> <Editable submitOnBlur={true} value={email} onSubmit={handleSubmit} onChange={setEmail} > <EditablePreview /> <EditableInput /> </Editable> </Box> <Box> <Heading size="xs" textTransform="uppercase"> Birthday </Heading> <Text pt="2" fontSize="sm"> {user.date_of_birth} </Text> </Box> <Box> <Heading size="xs" textTransform="uppercase"> Zip Code </Heading> <Text pt="2" fontSize="sm"> {user.zip_code} </Text> </Box> </Stack> </CardBody> </Card> ); } export default DadDetails;
关键修改点
- 将
defaultValue={user.email}改为value={email},绑定状态实现输入与预览同步 - 简化
onChange为onChange={setEmail},直接利用组件返回的新值更新状态 - 调整
handleSubmit参数为submittedValue,使用提交的实际值进行请求和状态更新,避免状态不一致
内容的提问来源于stack exchange,提问作者tehnerrelnz
相关产品推荐
相关产品推荐

