Перенаправление после публикации на другую страницу

#javascript #reactjs #typescript

#javascript #reactjs #typescript

Вопрос:

Я работаю над шаблоном кодирования react, где после нажатия кнопки отправки он показывает мне успешное сообщение и остается на той же странице. Я хотел бы добавить перенаправление на кнопку отправки в случае успеха без изменения дизайна. Мой компонент ./AskPage использует интерфейсы из ./Form . Как мне добавить перенаправление на страницу ./AskPage после нажатия кнопки отправить? Ниже приведен мой код

./ Код формы:

 import { FC, useState, createContext, FormEvent } from 'react';
import { PrimaryButton, gray5, gray6 } from './Styles';
/** @jsx jsx */
import { css, jsx } from '@emotion/core';

export interface Values {
  [key: string]: any;
}

export interface Errors {
  [key: string]: string[];
}

export interface Touched {
  [key: string]: boolean;
}
/* export interface onSubmit {
  [key: string]: any
} */

interface FormContextProps {
  values: Values;
  setValue?: (fieldName: string, value: any) => void;
  errors: Errors;
  validate?: (fieldName: string) => void;
  touched: Touched;
  setTouched?: (fieldName: string) => void;
}
export const FormContext = createContext<FormContextProps>({
  values: {},
  errors: {},
  touched: {},
});

type Validator = (value: any, args?: any) => string;

export const required: Validator = (value: any): string =>
  value === undefined || value === null || value === ''
    ? 'This must be populated'
    : '';

export const minLength: Validator = (value: any, length: number): string =>
  value amp;amp; value.length < length
    ? `This must be at least ${length} characters`
    : '';

interface Validation {
  validator: Validator;
  arg?: any;
}

interface ValidationProp {
  [key: string]: Validation | Validation[];
}

export interface SubmitResult {
  success: boolean;
  errors?: Errors;
}

interface Props {
  submitCaption?: string;
  validationRules?: ValidationProp;
  onSubmit: (values: Values) => Promise<SubmitResult>;
  successMessage?: string;
  failureMessage?: string;
}
export const Form: FC<Props> = ({
  submitCaption,
  children,
  validationRules,
  onSubmit,
  successMessage = 'Success!',
  failureMessage = 'Something went wrong',
}) => {
  const [values, setValues] = useState<Values>({});
  const [errors, setErrors] = useState<Errors>({});
  const [touched, setTouched] = useState<Touched>({});
  const [submitting, setSubmitting] = useState(false);
  const [submitted, setSubmitted] = useState(false);
  const [submitError, setSubmitError] = useState(false);

  const validate = (fieldName: string): string[] => {
    if (!validationRules) {
      return [];
    }
    if (!validationRules[fieldName]) {
      return [];
    }
    const rules = Array.isArray(validationRules[fieldName])
      ? (validationRules[fieldName] as Validation[])
      : ([validationRules[fieldName]] as Validation[]);
    const fieldErrors: string[] = [];
    rules.forEach(rule => {
      const error = rule.validator(values[fieldName], rule.arg);
      if (error) {
        fieldErrors.push(error);
      }
    });
    const newErrors = { ...errors, [fieldName]: fieldErrors };
    setErrors(newErrors);
    return fieldErrors;
  };

  const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    if (validateForm()) {
      setSubmitting(true);
      setSubmitError(false);
      const result = await onSubmit(values);
      setErrors(result.errors || {});
      setSubmitError(!result.success);
      setSubmitting(false);
      setSubmitted(true);
    }
  };

  const validateForm = () => {
    const newErrors: Errors = {};
    let haveError: boolean = false;
    if (validationRules) {
      Object.keys(validationRules).forEach(fieldName => {
        newErrors[fieldName] = validate(fieldName);
        if (newErrors[fieldName].length > 0) {
          haveError = true;
        }
      });
    }
    setErrors(newErrors);
    return !haveError;
  };

  return (
    <FormContext.Provider
      value={{
        values,
        setValue: (fieldName: string, value: any) => {
          setValues({ ...values, [fieldName]: value });
        },
        errors,
        validate,
        touched,
        setTouched: (fieldName: string) => {
          setTouched({ ...touched, [fieldName]: true });
        },
      }}
    >
      <form noValidate={true} onSubmit={handleSubmit}>
        <fieldset
          disabled={submitting || (submitted amp;amp; !submitError)}
          id="fieldset"     >
          {children}
          <div id="children"          >
            <PrimaryButton type="submit">{submitCaption}</PrimaryButton>
          </div>
          {submitted amp;amp; submitError amp;amp; (
            <p id="failure"            >
              {failureMessage}
            </p>)}
          {submitted amp;amp; !submitError amp;amp; (
            <p id="success"            >
              {successMessage}
            </p>)}
        </fieldset>
      </form>
    </FormContext.Provider>
  );
};
 

Мой ./AskpPage:

 import React, { useState, FC } from 'react';
import { Page } from './Page';
import { Form, required, minLength, Values } from './Form';
import { Field } from './Field';
import { postQuestion } from './QuestionsData';
import { BrowserRouter, Route, Redirect, Switch, Link } from 'react-router-dom';
import { isPropertySignature } from 'typescript';

export const AskPage = () => {
  const handleSubmit = async (values: Values) => {
    const question = await postQuestion({
      title: values.title,
      content: values.content,
      userName: 'Fred',
      created: new Date(),
    });
    return { success: question ? true : false };
  };

  return (
    <Page title="Ask a Question">
 {/* I want to add a redirect to this form once I click Submit Your Question */}
      <Form
        submitCaption="Submit Your Question"
        validationRules={{
          title: [{ validator: required }, { validator: minLength, arg: 10 }],
          content: [{ validator: required }, { validator: minLength, arg: 20 }],
        }}
        onSubmit={handleSubmit}
        failureMessage="There was a problem with your question"
        successMessage="Your question was successfully submitted"
      >
        <Field name="title" label="Title" />
        <Field name="content" label="Content" type="TextArea" />
      </Form>
    </Page>
  );
};
export default AskPage;
 

Ответ №1:

Я использую этот пример кода для перенаправления после отправки моей формы в react. Я в основном делаю все, что нужно, и сохраняю ответ, затем вызываю соответствующую функцию, чтобы перейти на соответствующую страницу. Затем эта страница может получить ответ. Другим способом было бы использовать props и импортировать другую страницу…

 function viewPage() {
  let url = window.location.origin;
  console.log('viewPage', url)
  url=url.concat('/SelfAssessment')
  window.open(url, "_blank");
}
 

Комментарии:

1. итак, после <./Form> мне просто сделать {ViewPage} ?

2. Когда вы кодируете в React, вы просто вызываете функцию после того, как обработали данные из формы. Мне кажется, вы обрабатываете данные в handlesubmit, поэтому в конце проверки есть строка: setSubmitted(true); введите ViewPage(); в следующей строке, и, возможно, это то, что вы хотите. Функция ViewPage() должна находиться в файле /Form, вырезаться, вставляться и редактироваться соответствующим образом. Переименуйте и перепишите функцию, чтобы перейти туда, куда вы хотите, по своему усмотрению.