我在其他地方看到过这个问题,但没有一个答案对我有帮助。我在 url 中使用了一个参数,我想使用 useParam 挂钩访问它,然后查询我的后端。
解构后的参数类型为 'string | undefined' - 有没有办法明确键入解构的查询参数?我想避免有未定义的值。我知道我可以处理期望参数的函数中的未定义值,但如果可能的话,我宁愿从源头上删除问题。
其他答案建议将解构的参数值与路由组件中规定的参数名称进行匹配,但我的已经匹配了。这可能与“/journalEntries”下的嵌套路由有关,即因为其他路由 - 没有参数 - 可能在“journalEntries”路由上?我试图通过删除其他子路线来解决这个问题,但没有帮助。
路由:
const Routing = () => {
return (
<MainViewContainer>
<NavBar />
<>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/thoughtRecords" element={<ThoughtRecordPage />} />
<Route path="/journalEntries">
<Route
index
element={
<JournalPage>
<JournalContainer />
</JournalPage>
}
/>
=========================================================
ROUTE I WANT TO DESTRUCTURE THE 'id' PARAMETER FROM:
<Route
path=":id"
element={
<JournalPage>
<JournalEntry />
</JournalPage>
}
/>
=========================================================
<Route
path="create"
element={
<JournalPage>
<JournalEntryForm />
</JournalPage>
}
/>
</Route>
</Routes>
</>
</MainViewContainer>
);
};
export default Routing;
包含指向单个“日记条目”的链接的组件:
const JournalContainer = () => {
const { journalEntries } = useDataContext();
return (
<>
<div className="flex flex-col items-center">
{journalEntries.map((journalEntry) => {
return (
<div
className="w-1/3 border flex justify-between p-1 m-1"
key={journalEntry._id}
>
======================================================================
LINK TO JOURNAL ENTRY
<Link
to={`/journalEntries/${journalEntry._id}`}
className="w-3/4 flex justify-between"
>
======================================================================
<span className="">{journalEntry.title}</span>
<span className="text-xs">
{new Date(journalEntry.createdAt).toDateString()}
</span>
</Link>
<button
onClick={async () => await deleteJournalEntry(journalEntry._id)}
className="mr-0"
>
Delete
</button>
</div>
);
})}
<Link
className="w-1/3 border text-center p-1 m-1"
to={'/journalEntries/create'}
>
Create a Journal Entry
</Link>
</div>
</>
);
};
export default JournalContainer;
依赖于解构参数的'Journal Entry'组件:
const { id } = useParams(); // is typed as 'string | undefined'
const methods = useForm({
defaultValues: async () => await getJournalEntryById(id), // this function expects a string
});
const navigate = useNavigate();
const [saveCopy, setSaveCopy] = useState(false);
const [readOnly, setReadOnly] = useState(true);
const submissionHandler: SubmitHandler<CreateJournalEntryType> = async (
data
) => {
await updateJournalEntryById(id, data); // this function expects a string
if (saveCopy) {
writeJournalEntryToFile(data);
}
navigate('/journalEntries');
};
return (
<FormProvider {...methods}>
<form
className="flex flex-col justify-evenly items-center border p-10 h-1/2"
onSubmit={methods.handleSubmit(submissionHandler)}
>
<button className="mr-auto" onClick={() => navigate(-1)}>
Go Back
</button>
<JournalEntryFormFields readOnly={readOnly} setReadOnly={setReadOnly} />
<div className="flex w-full justify-evenly items-center">
<button type="submit" className="border p-2 m-1">
Submit Journal Entry
</button>
<div className="flex items-center border p-1">
<input
type="checkbox"
className="m-1"
onChange={() => setSaveCopy(!saveCopy)}
/>
<label className="m-1" htmlFor="save-journal-entry-checkbox">
Save a copy to file
</label>
</div>
</div>
</form>
</FormProvider>
);
};
export default JournalEntry;
在 React Router 中,TypeScript 编译器目前无法推断参数值不是未定义的。
相反,你可以做的是使用不变检查。这种方法广受欢迎,并在 React Router 内部使用,以断言程序状态的给定属性始终为真。
不变检查的工作原理如下:
const {id} = useParams();
invariant(id); // From this point on "id" is correctly treated as non-undefined
“不变量”的实现可能如下所示:
function invariant(value: unknown): asserts value {
if (value) {
return;
}
throw new Error("Invariant violation");
}
或者,您可以从 https://npmjs.com 下载不变量的众多实现之一 请注意:Facebook 不变量的镜像包含专为 Facebook 目的设计的错误处理逻辑。
如果您知道
id
路由路径参数将始终是定义的字符串,那么您可以简单地键入/转换参数值。像下面这样简单的东西应该/可以工作。
const { id } = useParams() as { id: string };