جاوااسکریپت - چگونه بدون مقادیر اولیه در فرم با استفاده از Formik و TypeScript داشته باشیم؟


در اپلیکیشن React Typescript من، یک فرم Formik وجود دارد با فیلدهایی که نیازی به پر شدن با هیچ مقداری ندارند (یعنی متن جایگزین قابل مشاهده است).

چگونه میتوانیم به این دست یابیم؟

تلاش 1:

در initialValues فرمیک، من سعی کردم هیچ مقداری که فرم باید در ابتدا خالی باشد را تعریف نکنم.

<Formik
    initialValues={{
        itemType: 'any',
    }}
    ...
>
interface Values {
    itemType: string;
    minPrice?: number;
    maxPrice?: number;
}

با این حال، هنگامی که کاربر چیزی را در هر یک از این فرمها تایپ میکند، کنسول JS مرورگر هشدار زیر را نشان میدهد:

index.js:1 هشدار: یک کامپوننت در حال تغییر یک ورودی کنترلنشده به ورودی کنترلشده است. این احتمالاً به این دلیل است که مقدار از undefined به یک مقدار تعریفشده تغییر میکند، که نباید اتفاق بیفتد. برای طول عمر کامپوننت، بین استفاده از عنصر ورودی کنترلشده یا کنترلنشده تصمیم بگیرید. اطلاعات بیشتر: https://reactjs.org/link/controlled-components در ورودی


تلاش ۲:

تلاش کردم این مقادیر را در خصوصیت initialValues فرمیک به null تنظیم کنم،

<Formik
    initialValues={{
        itemType: 'any',
        minPrice: null,
        maxPrice: null,
    }}

    ...

اما TypeScript خطا میدهد:

نوع 'string' قابل اختصاص به نوع 'never' نیست. TS2322

Type 'string' is not assignable to type 'never'.  TS2322

    66 |                 <Formik
    67 |                     initialValues={{
  > 68 |                         itemType: 'any',
       |                         ^
    69 |                         minPrice: null,

اپلیکیشن React حتی شروع هم نمیشود!


کد کامل

import { Button, Modal, Form, Row, Col } from 'react-bootstrap';
import { Formik, FormikHelpers } from 'formik';


interface Values {
    itemType?: string;
    minPrice?: number;
    maxPrice?: number;
}


export function FormModal({show, handleClose, updateFilter}: IModal): JSX.Element {
    return (
        <Modal show={show} onHide={handleClose}>
            <Modal.Body>
                <Formik
                    initialValues={{
                        itemType: 'any',
                        minPrice: null,
                        maxPrice: null,
                    }}
                    validationSchema={schema}
                    onSubmit={(
                        values: Values,
                    ) => {
                        updateFilter(values);
                        handleClose();
                    }}
                >
                    {( {values, errors, touched, handleChange, handleBlur, handleSubmit, isSubmitting, setFieldValue }) => (
                        <Form id="updateFilterForm" onSubmit={handleSubmit}>

                            <Form.Group as={Row} controlId="formItemType">
                                <Form.Label column sm="3">Item Type</Form.Label>
                                <Col sm="9">
                                    <Select 
                                        name="itemType" 
                                        options={itemTypeOptions} 
                                        onChange={option => setFieldValue("itemType", option!.value)} 
                                        onBlur={handleBlur} 
                                        values={values.itemType} 
                                    />
                                </Col>
                            </Form.Group>

                            <Form.Group as={Row} controlId="formPrice">
                                <Form.Label column sm="3">Price Range</Form.Label>
                                <Col sm="9">
                                    <Form.Row>
                                        <Col>
                                        <Form.Control 
                                            type="number" 
                                            name="minPrice" 
                                            onChange={handleChange} 
                                            onBlur={handleBlur} 
                                            value={values.minPrice} 
                                            placeholder="Min" 
                                        />
                                        </Col>
                                        <Col>
                                        <Form.Control 
                                            type="number" 
                                            name="maxPrice" 
                                            onChange={handleChange} 
                                            onBlur={handleBlur} 
                                            value={values.maxPrice} 
                                            placeholder="Max" 
                                        />
                                        </Col>
                                    </Form.Row>
                                </Col>
                            </Form.Group>

                        </Form>  
                    )}
                </Formik>
            </Modal.Body>
        </Modal>
    )
}

پاسخ شماره ۱

تا جایی که میتوانم ببینم، به نظر میرسد شما رابط خود را در هیچجا تعریف نکردهاید.

[ ... ]
const initialValues: Values = {
   itemType: 'any',
   minPrice: undefined,
   maxPrice: undefined,
};

<Formik initialValues={initialValues} {...}>

هنگام کار با اینترفیسها به یاد داشته باشید که هنگام تنظیم مقادیر اختیاری، اگر نیاز است مقدار اولیهای تعریف کنید، از undefined استفاده کنید نه null.

برنامه شما اکنون باید قوانین تایپاسکریپت را رعایت کرده و کامپایل شود.