reactjs - Đánh kiểu cho thuộc tính location.state trên cơ sở từng component sử dụng react-router-dom
Tôi có ý tưởng để xác định location.state có thể thuộc loại nào đối với một component không có trạng thái nhất định. Tôi đã tìm thấy một vài bài viết dựa trên kiểu RouteComponentProps nhưng tôi không thể hiểu rõ các chi tiết.
Giả sử trong ví dụ này, tôi mong rằng thuộc tính location.state sẽ có kiểu
type StateType = {
id: number,
type: number
}
hoặc để type` thậm chí là một liệt kê. Điều này có thể được thực hiện không?
import React from 'react';
import { withRouter, RouteComponentProps } from 'react-router-dom';
const Index = ({ location, history }) => {
return (
<div>Test</div>
)
}
export default withRouter(Index)
Câu trả lời #1
Kiểu RouteComponentProps của react-router là một kiểu tổng quát. Đây là cách bạn có thể định nghĩa trạng thái vị trí với kiểu tùy chỉnh của bạn (tôi đã chỉnh sửa ví dụ của bạn):
import React from 'react';
import { withRouter, RouteComponentProps } from 'react-router-dom';
type StateType = {
id: number,
type: number
}
type IndexProps = RouteComponentProps<{}, {}, StateType>;
const Index: React.FC<IndexProps> = ({ location, history }) => {
return (
<div>{location.state && (
<ul>
<li>{location.state.id}</li>
<li>{location.state.type}</li>
</ul>
)}</div>
);
}
export default withRouter(Index);
Một số điều cần rút ra:
- bạn có lẽ nên luôn kiểm tra xem
location.statecó được định nghĩa hay không, có thể xảy ra trường hợp state không được truyền vì bất kỳ lý do gì - chúng tôi đã phải thêm kiểu chính xác vào chính component thông qua kiểu generic
React.FC(mặc dù, có những cách khác để làm điều đó...) RouteComponentPropsthực sự nhận ba loại để được định nghĩa chính xác:- đầu tiên (trống
{}trong ví dụ của tôi) - loại của các tham số của<Route />
- đầu tiên (trống
- thứ hai (trống
{}trong ví dụ của tôi) - loại của context của<StaticRouter /> - và cuối cùng, thứ ba (
StateTypetrong ví dụ của tôi) - loại trạng thái của địa điểm
Đối tượng location cũng có thể được tìm thấy trong history.location, nhưng nó không có kiểu dữ liệu và không nên được sử dụng, như đã nêu trong tài liệu:
... Đối tượng history có thể thay đổi. Do đó, được khuyên nên truy cập location từ các props render của
<Route>, không phải từhistory.location. ...
Câu trả lời #2
Bạn có thể sử dụng kiểu tổng quát Location và đơn giản mở rộng nó với StateType.
import { Location } from 'history';
type LocationProps = Location<StateType>;
Hãy nhớ gõ thành phần của bạn một cách đúng đắn:
interface IndexProps {
location: LocationProps;
classes: // your type
history: // your type
}
const Index = ({ classes, location, history }: IndexProps) => {
