我将 useHistory (react-router-dom) 变量作为参数发送给employee.service,其中我使用带有状态和路径名的“history.push”方法。不幸的是,我似乎无法找出正确的类型。我用过:
History<unknown>
History<Location>
但两人似乎都不明白我所经历的状态。有谁知道如何强输入这个?非常感谢任何帮助!
服务中的create方法:
export const createEmployee = async (body: IEmployee, history: any) => {
try {
const employeesResponse = await fetch(`http://localhost:3000/employees`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
if (employeesResponse.status !== 201) {
const response: IHttpResponse = {
status: employeesResponse.status,
error: {message: employeesResponse.statusText},
data: {content: ''}
}
return response
}
const employeeResult: IEmployee[] = await employeesResponse.json();
const response: IHttpResponse = {
status: employeesResponse.status,
error: {message: ''},
data: {content: employeeResult}
}
history.push({
pathname: '/',
state: { detail: 'reload', response: response },
});
} catch (error) {
console.log('error while creating', error);
const response: IHttpResponse = {
status: error.status,
error: {message: error.statusText},
data: {content: ''}
}
return response;
}
}
使用服务的组件
import React, { useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { Button, Input, Label } from 'reactstrap';
import FormGroup from 'reactstrap/es/FormGroup';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';
import Select from 'react-select';
import { useHistory } from 'react-router-dom';
import { gendersList, statusList } from '../models/lists/formLists';
import { IOptionType } from '../models/IOptionType';
import { createEmployee } from '../services/employee.service';
import { IEmployee } from './../models/IEmployee';
export const AddEmployeeForm = () => {
const history = useHistory();
const [gender, setGender] = useState<IOptionType>({ label: gendersList[0].label, value: gendersList[0].value });
const [status, setStatus] = useState<IOptionType>({ label: statusList[0].label, value: statusList[0].value });
const validationSchema = yup.object().shape({
firstname: yup.string().required().min(2),
lastname: yup.string().required().min(2),
email: yup.string().email().required(),
status: yup.object().shape({
label: yup.string(),
value: yup.string(),
}),
gender: yup.object().shape({
label: yup.string(),
value: yup.string(),
}),
});
const {
handleSubmit,
control,
formState: { errors },
register,
} = useForm({
resolver: yupResolver(validationSchema),
});
const handleGenderChange = (option: IOptionType) => {
setGender({ label: option.label, value: option?.value });
};
const handleStatusChange = (option: IOptionType) => {
setStatus({ label: option.label, value: option?.value });
};
const onSubmit = async (data: any) => {
console.log('errors', errors);
const body: IEmployee = {
first_name: data.firstname,
last_name: data.lastname,
email: data.email,
gender: gender.value ? gender.value : '',
status: status.value ? status.value : '',
};
console.log('Data', body);
createEmployee(body, history);
};
return (
<div className="col-12">
<form onSubmit={handleSubmit(onSubmit)}>
<FormGroup>
<Label for="firstname">First name</Label>
{errors.firstname && <p className="text-danger error-message">{errors.firstname.message}</p>}
<Input {...register('firstname')} />
</FormGroup>
<FormGroup>
<Label for="lastname">Last name</Label>
{errors.lastname && <p className="text-danger error-message">{errors.lastname.message}</p>}
<Input {...register('lastname')} />
</FormGroup>
<FormGroup>
<Label for="email">Email</Label>
{errors.email && <p className="text-danger error-message">{errors.email.message}</p>}
<Input {...register('email')} />
</FormGroup>
<FormGroup>
<Label for="gender">Gender</Label>
<Controller
name="gender"
control={control}
render={({ field: { onChange, onBlur, value, ref } }) => (
<Select
options={gendersList}
onChange={(value) => handleGenderChange({ value: value?.value, label: value?.label })}
onBlur={onBlur}
defaultValue={gender}
selected={value}
/>
)}
/>
</FormGroup>
<FormGroup>
<Label for="status">Status</Label>
<Controller
name="status"
control={control}
render={({ field: { onChange, onBlur, value, ref } }) => (
<Select
options={statusList}
onChange={(value) => handleStatusChange({ value: value?.value, label: value?.label })}
onBlur={onBlur}
value={status}
selected={value}
/>
)}
/>
</FormGroup>
<Button type="submit">Submit</Button>
</form>
</div>
);
};
您可以使用
RouterChildContext
访问 useHistory
类型。
const foo = (history: RouterChildContext['router']['history']) => {
history.push('/your-path');
}
这来自
react-router
类型声明文件:
// This is the type of the context object that will be passed down to all children of
// a `Router` component:
export interface RouterChildContext<Params extends { [K in keyof Params]?: string } = {}> {
router: {
history: H.History;
route: {
location: H.Location;
match: match<Params>;
};
};
}
我的解决方法是:
import { useHistory, useLocation } from "react-router-dom";
type THistory<T = unknown> = ReturnType<typeof useHistory<T>>
type TLocation<T = unknown> = ReturnType<typeof useLocation<T>>;
const goTo = (history: THistory<{payload: string}>) => {
history.push({
pathname: '/',
state: { payload: 'some data' },
});
}
您可能想看看 RouterProps 是如何定义的。也许有帮助。
import { useHistory, RouterProps } from 'react-router-dom';
你可以这样实现:
const history = useHistory<{ detail: string, response: IHttpResponse }>();
console.log(history.location.state.detail); // should log 'reload'
我查看了 useHistory 类型定义并导入了 H。然后我将 useHistory 变量键入为 H.history。
import * as H from 'history';
const history : H.history = useHistory();