使用 ref 从父函数组件传递时 useState 不更新数据
Posted
技术标签:
【中文标题】使用 ref 从父函数组件传递时 useState 不更新数据【英文标题】:useState not updating data when passing from parent function component using ref 【发布时间】:2021-12-10 02:17:30 【问题描述】:我正在尝试将数据发送到子函数组件,在该组件中我将表单字段与该数据绑定。它在第一次调用时工作正常,但是当我第二次调用时,数据从不更新状态,它总是显示第一个。
这是使用子组件引用的父组件
export default function Form1()
const [count, setCount] = useState(0);
const [counter, setCounter] = useState(10);
const AddNewRef = useRef();
const clickMe=() =>
setCount(count+1);
setCounter(counter*2);
AddNewRef.current.showDrawer(counter*2);
return (
<div>
<p>You clicked count: count & counter: counter times</p>
count > 10 ?
(
<p className='red'>your count is greater then 10</p>
) :
(
<p className='green'>your count is less then 10</p>
)
<button onClick=() => clickMe()>
Click me
</button>
<AddNew ref=AddNewRef Count=count Counter=counter />
</div>
)
这是子组件
const AddNew=forwardRef((props, ref) =>
const[objCounter, setobjCounter] = useState(null);
useImperativeHandle(
ref,
() => (
showDrawer(count)
setobjCounter(count);
//only shows at first click at parent, Not updating on 2nd, 3rd click from parent and so on....
),
)
return (
<>
<Drawer
title=<span> <i className='fa-solid fa-kaaba' /> Haj Setup Form</span>
width=window.innerWidth > 900 ? 800 : window.innerWidth - 50
onClose=onClose
visible=visible
bodyStyle= paddingBottom: 80
extra=
<Space>
<Button onClick=onClose>Cancel</Button>
<Button onClick=onClose type="primary">
Submit
</Button>
</Space>
>
<Form
style=display: formVisible ? 'block' : 'none'
form=form
layout="vertical"
onFinish=onFinish
onFinishFailed=onFinishFailed
autoComplete="off"
hideRequiredMark>
<Row gutter=16>
<Col xs=24 sm=24 md=24 lg=24>
<Form.Item
name="packageName"
label="Package Name"
rules=[ required: true, message: 'Please enter package name' ]
initialValue=objCounter
>
<Input style=width: '100%'
maxLength=100 />
</Form.Item>
</Col>
</Row>
</Form>
</Drawer>
</>
)
);
export default AddNew
【问题讨论】:
所以你想在什么时候更新子组件的本地状态(AddNew
)。在父组件中单击按钮?您要发送给showDrawer
的值是多少?据我所知,将状态更新排入队列,但只发送当前状态值。
不清楚您声称没有更新。这是一个正在运行的codesandbox,本地objCounter
状态正在更新。您能否更新您的问题以包含所有相关代码?
我没有看到子组件内部使用了任何 ref。检查反应文档以了解如何正确使用 useImperativeHandle 和 useRef
@ABDULLOKHMUKHAMMADJONOV 引用在子组件的useImperativeHandle
钩子中使用。
嗨 Drew Reese,我在代码框上做了一些更改,请检查是否有另一个错误
【参考方案1】:
由于状态更新正在工作并且您只是想更新表单字段,您可以使用从useForm
挂钩返回的form
引用来更新表单状态。在这种情况下,请更新 packageName
字段。
const AddNew = forwardRef((props, ref) =>
const [objCounter, setobjCounter] = useState(13);
const [visible, setVisible] = useState(false);
const [formVisible, setformVisible] = useState(true);
const [form] = Form.useForm();
useImperativeHandle(ref, () => (
showDrawer(count)
setobjCounter(count);
setVisible(true);
form.setFieldsValue(
packageName: count // <-- update the specific field
);
));
const onClose = () =>
setVisible(false);
;
return (
...
);
);
【讨论】:
Booooom Booom 非常感谢 Drew。 是的,但是如果 antd form 有任何方法可以一次绑定所有字段,比如 form.setFieldsValues(props?.editData)... ?这将非常容易 它也完成了,很好,它也已解决和增强。 @MuhammadFaheemChughtai 我对 antd 组件不是很熟悉,但我的猜测是setFieldValues
接受一个键值对对象,代表您的 any 字段,通过name
属性。例如,如果您有 2 个输入,firstName
和 lastName
,那么您可以想象使用 setFieldValues( firstName: 'Drew', lastName: 'Reese' )
。
谢谢你,Drew,现在看起来不错,我是 ant 新手,如果有任何问题,我会问你,再次感谢。以上是关于使用 ref 从父函数组件传递时 useState 不更新数据的主要内容,如果未能解决你的问题,请参考以下文章