#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, вырезаться, вставляться и редактироваться соответствующим образом. Переименуйте и перепишите функцию, чтобы перейти туда, куда вы хотите, по своему усмотрению.