export default function SearchPage() {
const [searchString, setSearchString] = React.useState("");
const [apiCall, setApiCall] = React.useState<() => Promise<Collection>>();
const {isIdle, isLoading, isError, error, data} = useApi(apiCall);
const api = useContext(ApiContext);
useEffect(()=>console.log("APICall changed to", apiCall), [apiCall]);
const doSearch = (event: React.FormEvent) => {
event.preventDefault();
setApiCall(() => () => api.search(searchString));
};
const doNext = () => {
var next = api.next;
if (next) {
setApiCall(()=>(() => next)());
}
window.scrollTo(0, 0);
}
const doPrev = () => {
if (api.prev) {
setApiCall(() => api.prev);
}
window.scrollTo(0, 0);
}
return (
<>
<form className={"searchBoxContainer"} onSubmit={doSearch}>
<TextField
label={"Search"}
variant={"filled"}
value={searchString}
onChange={handleChange}
className={"searchBox"}
InputProps={{
endAdornment: (
<IconButton onClick={() => setSearchString("")}>
<ClearIcon/>
</IconButton>
)
}}
/>
<Button type={"submit"} variant={"contained"} className={"searchButton"}>Go</Button>
</form>
{
(isIdle) ? (
<span/>
) : isLoading ? (
<span>Loading...</span>
) : isError ? (
<span>Error: {error}</span>
) : (
<Paper className={"searchResultsContainer"}>
<Box className={"navButtonContainer"}>
<Button variant={"contained"}
disabled={!api.prev}
onClick={doPrev}
className={"navButton"}>
{"< Prev"}
</Button>
<Button variant={"contained"}
disabled={!api.next}
onClick={doNext}
className={"navButton"}>
{"Next >"}
</Button>
</Box>
<Box className={"searchResults"}>
{
data && data.items().all().map(item => (
<span className={"thumbnailWrapper"}>
<img className={"thumbnail"}
src={item.link("preview")?.href}
alt={(Array.from(item.allData())[0].object as SearchResponseDataModel).title}/>
</span>
))
}
</Box>
<Box className={"navButtonContainer"}>
<Button variant={"contained"}
disabled={!api.prev}
onClick={doPrev}
className={"navButton"}>
{"< Prev"}
</Button>
<Button variant={"contained"}
disabled={!api.next}
onClick={doNext}
className={"navButton"}>
{"Next >"}
</Button>
</Box>
</Paper>
)
}
</>
)
}
さまざまな理由で、自分の状態に関数が保存されています(react-query
ライブラリで使用するためのものです)。ただし、更新しようとすると、非常に奇妙な動作が見られます。いずれかの場合にはdoSearch
、doNext
、またはをdoPrev
呼ばれて、それが成功した状態を更新-useEffect
フックが適切に発射され、私は、コンソールにメッセージを見ることができます-しかし、ウィンドウが失われ、フォーカスを取り戻すまでには再レンダリングトリガではないです。
この問題で私が見た他のほとんどの人は、配列をその状態で格納し、新しい配列を作成するのではなく配列を更新しているので、フックはそれを新しいオブジェクトとして扱わず、再レンダリングします起こりません。配列は使用していませんが、関数を使用しており、さまざまな関数オブジェクトを渡しています。私は絶対に困惑していて、何が起こっているのか分かりません。
編集:レンダリングが起動に失敗したのではないようですが、クエリフックは入力が変更されたことに気づいていませんか?上記のコードを編集して関数全体を表示しました。カスタムフックは以下のとおりです。
function useApi(func?: () => Promise<Collection>) {
return useQuery(
["doApiCall", func],
func || (async () => await undefined),
{
enabled: !!func,
keepPreviousData: true
}
)
}
queryKeyに関数を入れることはできません。キーはシリアル化可能である必要があります。参照:https://react-query.tanstack.com/guides/query-keys#array-keys
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加