You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Formik多步骤表单字段验证及动态组件传参问题求助

Solution for Formik Multi-Step Form: Props Passing & Two-Digit Validation

Hey there! Let's break down how to fix your two key issues with the Formik multi-step form: passing props to dynamically rendered components, and implementing the two-digit input validation with error messages.

1. Passing Props to Dynamically Rendered Components

The problem with your current <div>{pages[state]}</div> approach is that you're directly rendering the component without a way to pass props. Instead, we'll reference the component as a variable and render it with JSX, which lets us pass any props we need (like Formik's errors and touched).

Step 1: Update the SignUp Component

Modify the Formik render block to render the current page component with props:

const SignUp = () => { 
  const currentPageIndex = useSelector((state: RootState) => state); 
  console.log("current page index", currentPageIndex); 
  const dispatch = useDispatch(); 

  // Get the current page component from your pages array
  const CurrentPage = pages[currentPageIndex];

  return ( 
    <Formik 
      initialValues={{ firstName: "", lastName: "", email: "", idealWeight: "" }} // Added idealWeight for semantic clarity
      onSubmit={values => { 
        setTimeout(() => { 
          alert(JSON.stringify(values, null, 2)); 
        }, 500); 
      }} 
      render={({ errors, touched, isValidating }) => ( 
        <Form> 
          {/* Render the current page with Formik props */}
          <CurrentPage errors={errors} touched={touched} />

          <button type="button" onClick={() => { 
            dispatch(decrement()); 
          }} > 
            Prev 
          </button> 
          <button type="button" onClick={() => { 
            pages.length - 1 <= currentPageIndex ? console.log("No more pages") : dispatch(increment()); 
          }} > 
            Next 
          </button> 
        </Form> 
      )} 
    /> 
  ); 
};

Step 2: Update Page2 to Receive Props

Now make sure Page2 accepts the props and passes them down to your Input component:

const Page2 = ({ errors, touched }) => { 
  return ( 
    <> 
      <h1> What is your <span id="idealWeightText">ideal weight</span> that you want to reach? </h1> 
      <Input 
        name={"idealWeight"} // Renamed to match initialValues
        htmlFor={"idealWeight"} 
        type={"number"} 
        validation={validateKilograms}
        errors={errors}
        touched={touched}
      /> 
    </> 
  ); 
};

2. Implement Two-Digit Validation & Error Messages

Next, we'll create the validation function and update the Input component to display error messages when validation fails.

Step 1: Create the Validation Function

This function checks if the input is a valid two-digit number (10-99):

const validateKilograms = (value) => {
  let error;
  if (!value) {
    error = "Weight is required";
  } else {
    const numValue = Number(value);
    if (isNaN(numValue) || numValue < 10 || numValue > 99) {
      error = "Please enter a valid two-digit number (10-99)";
    }
  }
  return error;
};

Step 2: Update the Input Component to Show Errors

Modify the Input component to accept errors and touched, then render the error message when the field has been touched and has an error:

// Extend FieldProps to include errors and touched
interface InputProps extends FieldProps {
  errors?: Record<string, string>;
  touched?: Record<string, boolean>;
}

const Input: React.FC<InputProps> = ({ 
  name, 
  onChange, 
  htmlFor, 
  type, 
  validation, 
  placeholder,
  errors,
  touched
}) => { 
  return ( 
    <div style={{ marginBottom: '16px' }}>
      <label htmlFor={name}> 
        <Field 
          type={type} 
          name={name} 
          placeholder={placeholder} 
          validate={validation} 
          onChange={onChange} 
        /> kg 
      </label>
      {/* Show error message only if field is touched and has an error */}
      {touched?.[name] && errors?.[name] && (
        <div style={{ color: '#dc2626', fontSize: '0.875rem', marginTop: '4px' }}>
          {errors[name]}
        </div>
      )}
    </div>
  ); 
};

Key Notes

  • I renamed the field from firstName to idealWeight in Page2 to make it semantically correct (since it's for weight, not a name).
  • The validation function checks for empty values, non-numeric inputs, and values outside the 10-99 range.
  • Error messages only show after the user has interacted with the field (touched[name] is true), which is a better UX practice.

内容的提问来源于stack exchange,提问作者Gim-Cojocaru Raul-Cristian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:17:39