我目前正在我的网站上开发移动签名功能。我正在处理三个组件:Form.js(父级,使用 Formik 作为表单)、Admin.js(Form 的子级)和 Signature.js(Admin 的子级)。
当您以纵向模式到达此页面(表单的管理部分)时,它会呈现一条消息,要求您将手机横向进行签名。当您转向横向时,会弹出一个按钮:“单击此处签名”。当您单击它时,会弹出一个带有签名画布(react-signature-canvas)的全屏 material-ui 对话框。您签名,然后单击“保存并关闭”关闭全屏对话框,然后单击“保存签名”将签名保存到您的个人资料中。
使用断点,我发现当您单击对话框中的“保存并关闭”将其关闭时,状态会与签名一起正确保存。但是当您在表单的“管理”部分单击“保存签名”时,状态已重置为其初始状态 null。
我相信解决方案是使用 forwardRef 钩子,但问题是我看到的大多数示例都是将 ref 从一个组件转发到另一个组件,我认为我需要让它像我的组件一样通过一个附加组件是结构化的(从签名 --> 传递到管理员 --> 到表单)。 我需要从 Signature.js 到 Form.js 获取 SignatureCanvas (react-signature-canvas) 的引用。以下是每个文件的相关信息:
Signature.js
const Signature = forwardRef((props, ref) => {
return (
<SignatureCanvas
backgroundColor="transparent"
canvasProps={{
width: mobileWidth,
height: mobileHeight - 60,
className: 'sigCanvas',
}}
penColor="black"
ref={ref}
/>
);
};
Admin.js
const Admin = () => {
const { values } = useFormikContext();
const signatureRef = useRef(null);
return (
<Signature values={values} ref={signatureRef} />
);
};
Form.js
const Form = () => {
const { values } = useFormikContext();
const signatureRef = useRef(null);
return (
<Admin ref={signatureRef} />
);
};
我研究并认为我可能需要使用 useCallback 钩子而不是转发 ref 或根本使用 refs,但我不确定如何实施,如果这是正确的解决方案。我还尝试在 Form 组件中设置状态并将其传递给 Admin 然后传递给 Signature 但没有任何运气。任何帮助将不胜感激!
答案 0 :(得分:1)
我不确定这是否能解决您的问题,但您可以通过多次使用 ref
将 forwardRef
传递给多个组件。
const DeeplyNestedComponent = forwardRef((_, ref) => <input ref={ref} />);
const NestedComponent = forwardRef((_, ref) => (
<DeeplyNestedComponent ref={ref} />
));
const BaseComponent = () => {
const [inputValue, setInputValue] = useState('');
const ref = useRef();
return (
<>
<p>Last input value: "{inputValue}"</p>
<NestedComponent ref={ref} />
<button onClick={() => setInputValue(ref.current.value)}>
Read input
</button>
</>
);
};