使用 forwardRef 反应总是更新子组件,即使使用备忘录
Posted
技术标签:
【中文标题】使用 forwardRef 反应总是更新子组件,即使使用备忘录【英文标题】:React using forwardRef always update child component even using memo 【发布时间】:2020-10-04 17:24:03 【问题描述】:所以我有一个 DatePicker ChildComponent,我需要通过 Parent 的forwardRef
访问它的ref
。基本上一切正常。
但是有一个问题。
每次我在父 Other ChildComponents 上更新与 DatePickerChild 没有任何关系的内容时, DatePicker 仍在渲染,即使它不应该渲染。
我尝试删除 ref 从父级到子级的传递,然后每次我对要解决的其他组件进行更新时,该组件都不再重新渲染。
<NativeDatePicker
ref=datePickerRef // <-- When I comment this component is not rendering anymore.
currentDate=values.birthday
onDateChange=handleBirthdayChange
/>
我已经开始使用回调记忆,通过使用useCallback
进行优化,但仍然没有运气。
下面是我的代码:
DatePicker.tsx
type Props =
// ref: RefObject<DatePicker>;
currentDate: string | Date | undefined;
onDateChange: (newDate: string) => void;
;
const NativeDatePicker = forwardRef(
( currentDate, onDateChange : Props, ref: any) =>
console.log('tadah!');
return (
<DatePicker
ref=ref
style=wrapperStyle.wrapper
date=currentDate
mode="date"
placeholder="select date"
format="YYYY-MM-DD"
// minDate="2016-05-01"
// maxDate=Date.now()
confirmBtnText="Confirm"
cancelBtnText="Cancel"
customStyles=styles
onDateChange=onDateChange
/>
);
,
);
const MemoizedNativeDatePicker = memo(NativeDatePicker);
我不会只显示我的 ParentComponent 中的所有代码,只显示我传递给 DatePicker 的 props 和 refs。
// Memoized Callback Function
const handleBirthdayChange = useCallback(
(newDate: string) => setFieldValue('birthday', newDate),
[setFieldValue],
);
const datePickerRef = createRef<DatePicker>();
const datePickerRefOnPress = () => datePickerRef.current!.onPressDate();
我错过了什么吗?感谢您的帮助。
【问题讨论】:
【参考方案1】:您正在使用createRef
创建一个引用,在每次重新渲染时都会返回一个新的引用实例,因此将导致使用React.memo
优化子重新渲染失败。
您应该改为使用useRef
钩子作为功能组件来创建引用
const datePickerRef = useRef<DatePicker>();
【讨论】:
很高兴有帮助:-)以上是关于使用 forwardRef 反应总是更新子组件,即使使用备忘录的主要内容,如果未能解决你的问题,请参考以下文章
useCallBack,useMemo,forwardRef,useImperativeHandle用法总结
React hook 中connect和forwardRef连用会导致传入子组件的ref失效
createRef和useRef区别——useRef的使用——forwardRef完成类组件的绑定—— useImperativeHandle——映射ref对象——更新同步
createRef和useRef区别——useRef的使用——forwardRef完成类组件的绑定—— useImperativeHandle——映射ref对象——更新同步