0

我目前正在我的网站上开发移动签名功能。我要处理三个组件:Form.js(父级,使用 Formik 作为表单)、Admin.js(Form 的子级)和 Signature.js(Admin 的子级)。

当您以纵向模式到达此页面(表单的管理部分)时,它会呈现一条消息以将您的手机横向切换为签名。当您转为横向时,会弹出一个按钮:“单击此处签名”。当您单击它时,会弹出一个带有签名画布 (react-signature-canvas) 的全屏 Material-ui 对话框。您签名,然后单击“保存并关闭”以关闭全屏对话框,然后单击“保存签名”以将签名保存到您的个人资料中。

使用断点,我发现当您在对话框中单击“保存并关闭”以关闭它时,状态正在正确地与签名一起保存。但是,当您在表单的“管理”部分单击“保存签名”时,状态已重置为其初始状态为 null。

我相信解决方案是使用 forwardRef 钩子,但问题是我看到的大多数示例都是将 ref 从一个组件转发到另一个组件,我认为我需要让它按照我的组件的结构方式通过一个附加组件(从签名 --> 到管理员 --> 到表单)。我需要将 SignatureCanvas (react-signature-canvas) 的引用从 Signature.js 获取到 Form.js。以下是每个文件的相关信息:

签名.js

const Signature = forwardRef((props, ref) => {
    return (
        <SignatureCanvas
           backgroundColor="transparent"
           canvasProps={{
              width: mobileWidth,
              height: mobileHeight - 60,
              className: 'sigCanvas',
           }}
           penColor="black"
           ref={ref}
         />
     );
};

管理员.js

const Admin = () => {
    const { values } = useFormikContext();
    const signatureRef = useRef(null);

    return (
       <Signature values={values} ref={signatureRef} />
    );
 };

表单.js

const Form = () => {
    const { values } = useFormikContext();
    const signatureRef = useRef(null);

    return (
       <Admin ref={signatureRef} />
    );
 };

我研究并认为也许我需要使用 useCallback 钩子而不是转发 ref 或根本使用 refs 但不确定如果这是正确的解决方案如何实现。我还尝试在表单组件中设置状态并将其传递给管理员,然后传递给签名,但没有任何运气。任何帮助将不胜感激!

4

1 回答 1

1

我不确定这是否能解决您的问题,但您可以通过多次使用来传递ref多个组件forwardRef

我创建了一个示例来展示您可以在CodePen上查看的示例。

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>
    </>
  );
};
于 2021-07-26T06:40:01.717 回答