最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Object is possibly 'null': TypeScript, React useRef & Formik innerRef - Stack Overflow

programmeradmin4浏览0评论

In my React/TypeScript app that uses Formik, I am getting the error

Object is possibly 'null'.  TS2531

    125 |             <Modal.Footer>
  > 126 |                 <Button variant="primary" type="submit" form="nicknameForm" disabled={!(formRef.current.isValid && formRef.current.dirty)}>Apply</Button>
        |                                                                                            ^
    127 |             </Modal.Footer>
    128 |         </Modal>
    129 |     )

Tried changing formRef.current.isValid to formRef!.current.isValid and formRef.current.dirty to formRef!.current.dirty but the error persists.

Why is this so, and how can we fix this error? Thank you!

import React, { useState, useEffect, useRef } from 'react';
import { Button, Modal, Form } from 'react-bootstrap';
import { Formik } from 'formik';

interface IModal {
    show: boolean;
    handleClose: () => void;
}

export function NicknameModal({show, handleClose}: IModal) {

    const formRef = useRef(null);

    return (
        <Modal show={show} onHide={handleClose}>
            <Modal.Header closeButton>
                <Modal.Title>My Title</Modal.Title>
            </Modal.Header>
            <Modal.Body>
                <Formik
                    initialValues={{
                        nickname: '',
                    }}
                    innerRef={formRef}
                    onSubmit={(
                        values,
                        { setSubmitting }
                    ) => {
                        setSubmitting(true);
                        handleClose();
                        setSubmitting(false);
                    }}
                >
                    {({values, errors, touched, handleChange, handleBlur, handleSubmit, isSubmitting, setFieldValue }) => (
                        <Form id="nicknameForm" onSubmit={handleSubmit}>
                            <Form.Group controlId="formNickname">
                                <Form.Label>Nickname</Form.Label>
                                <Form.Control type="text" name="nickname" onChange={handleChange} onBlur={handleBlur} value={values.nickname} />
                            </Form.Group>
                        </Form>  
                    )}
                </Formik>
            </Modal.Body>
            <Modal.Footer>
                <Button variant="primary" type="submit" 
                 disabled={!(formRef.current.isValid && formRef.current.dirty)}
                 form="nicknameForm">Apply</Button>
            </Modal.Footer>
        </Modal>
    )
}

UPDATE:

If const formRef = useRef(null); is changed to const formRef = useRef();, we now encounter a different error:

Type 'MutableRefObject<undefined>' is not assignable to type '((instance: FormikProps<{ nickname: string; }> | null) => void) & MutableRefObject<undefined>'.
  Type 'MutableRefObject<undefined>' is not assignable to type '(instance: FormikProps<{ nickname: string; }> | null) => void'.
    Type 'MutableRefObject<undefined>' provides no match for the signature '(instance: FormikProps<{ nickname: string; }> | null): void'.  TS2322

    71 |                         nickName: '',
    72 |                     }}
  > 73 |                     innerRef={formRef}
       |                     ^
    74 |                     onSubmit={(
    75 |                         values: Values,
    76 |                         { setSubmitting }: FormikHelpers<Values>

In my React/TypeScript app that uses Formik, I am getting the error

Object is possibly 'null'.  TS2531

    125 |             <Modal.Footer>
  > 126 |                 <Button variant="primary" type="submit" form="nicknameForm" disabled={!(formRef.current.isValid && formRef.current.dirty)}>Apply</Button>
        |                                                                                            ^
    127 |             </Modal.Footer>
    128 |         </Modal>
    129 |     )

Tried changing formRef.current.isValid to formRef!.current.isValid and formRef.current.dirty to formRef!.current.dirty but the error persists.

Why is this so, and how can we fix this error? Thank you!

import React, { useState, useEffect, useRef } from 'react';
import { Button, Modal, Form } from 'react-bootstrap';
import { Formik } from 'formik';

interface IModal {
    show: boolean;
    handleClose: () => void;
}

export function NicknameModal({show, handleClose}: IModal) {

    const formRef = useRef(null);

    return (
        <Modal show={show} onHide={handleClose}>
            <Modal.Header closeButton>
                <Modal.Title>My Title</Modal.Title>
            </Modal.Header>
            <Modal.Body>
                <Formik
                    initialValues={{
                        nickname: '',
                    }}
                    innerRef={formRef}
                    onSubmit={(
                        values,
                        { setSubmitting }
                    ) => {
                        setSubmitting(true);
                        handleClose();
                        setSubmitting(false);
                    }}
                >
                    {({values, errors, touched, handleChange, handleBlur, handleSubmit, isSubmitting, setFieldValue }) => (
                        <Form id="nicknameForm" onSubmit={handleSubmit}>
                            <Form.Group controlId="formNickname">
                                <Form.Label>Nickname</Form.Label>
                                <Form.Control type="text" name="nickname" onChange={handleChange} onBlur={handleBlur} value={values.nickname} />
                            </Form.Group>
                        </Form>  
                    )}
                </Formik>
            </Modal.Body>
            <Modal.Footer>
                <Button variant="primary" type="submit" 
                 disabled={!(formRef.current.isValid && formRef.current.dirty)}
                 form="nicknameForm">Apply</Button>
            </Modal.Footer>
        </Modal>
    )
}

UPDATE:

If const formRef = useRef(null); is changed to const formRef = useRef();, we now encounter a different error:

Type 'MutableRefObject<undefined>' is not assignable to type '((instance: FormikProps<{ nickname: string; }> | null) => void) & MutableRefObject<undefined>'.
  Type 'MutableRefObject<undefined>' is not assignable to type '(instance: FormikProps<{ nickname: string; }> | null) => void'.
    Type 'MutableRefObject<undefined>' provides no match for the signature '(instance: FormikProps<{ nickname: string; }> | null): void'.  TS2322

    71 |                         nickName: '',
    72 |                     }}
  > 73 |                     innerRef={formRef}
       |                     ^
    74 |                     onSubmit={(
    75 |                         values: Values,
    76 |                         { setSubmitting }: FormikHelpers<Values>

Share Improve this question edited Feb 10, 2021 at 21:25 Nyxynyx asked Feb 10, 2021 at 21:17 NyxynyxNyxynyx 63.6k163 gold badges505 silver badges855 bronze badges 2
  • You definitely need to set the generic on your useRef but I have to look up what the appropriate type would be for the innerRef of a Formik. – Linda Paiste Commented Feb 11, 2021 at 0:05
  • Does Formik even have an innerRef prop? Field does: formik.org/docs/api/field#innerref but I am not seeing it documented on Formik formik.org/docs/api/formik – Linda Paiste Commented Feb 11, 2021 at 0:09
Add a comment  | 

3 Answers 3

Reset to default 17

You need to set type for useRef, where FormValues is your form values

type FormValues = {};
useRef<FormikProps<FormValues>>(null);

https://github.com/formium/formik/issues/2600#issuecomment-693479057

Try with:

import { FormikProps } from "formik";

const formRef = useRef<FormikProps<any>>(null);

First of all you need to define a type for Formik initial values:

interface FormnameInitialValues {
  destination_city: string;
  cell_phone: string;
}

const initialValues: FormnameInitialValues = {
  cell_phone: "",
  destination_city: "",
};

Then define a form type for the ref state and set your form initial values type to it:

import { FormikProps } from "formik";

const formikRef = useRef<FormikProps<FormnameInitialValues>>(null);

Now you can use all the properties of Formik from the ref state without any typescript errors and also get the benefit of autocomplete.

if (formikRef.current) formikRef.current.resetForm();
if (formikRef.current) formikRef.current.isValid();
发布评论

评论列表(0)

  1. 暂无评论