举这个例子,
const SelectContainer = ({ excludeIds }) => {
const queryItems = (items) => {
return items.filter((item) => !excludeIds.includes(item.id)
}
console.log("SELECT CONTAINER EXCLUDEIDS:", excludeIds);
return (
<Select queryItems={queryItems} excludeIds={excludeIds} />
);
};
const Select = ({ queryItems, excludeIds, addItem }) => {
const [items, setItems] = useState(dummyItems);
const searchResults = (value) => {
console.log("SELECT EXCLUDEIDS:", excludeIds);
return queryItems(items);
}
return <SearchSelect search={searchResults} onItemSelect={(item) => addItem(item)} />;
};
excludeIds
通过 SelectContainer
的父组件进行的 API 调用进行更新。基本上,当通过 Select
选择某个项目时,addItem
将触发一些逻辑,最终更新传递到 SelectContainer 中的 exceptIds 以包含该添加项目的 ID,这样就不会重复。
当
excludeIds
从 [77]
更改为 [77, 78]
时,我希望 queryItems
开始排除 ID 为 77 和 78 的项目,但这仅在刷新或强制重新渲染容器时发生,并且子组件。
我认为我们如何将
queryItems
的引用传递给 Select
会导致即使 excludeIds
在 SelectContainer
组件中发生更改,它也不会更改。
我尝试在将
excludeIds
传递到 Select
之前打印它,并且它具有正确的值 [77, 78]
,但是在 Select.searchResults
函数中打印它会产生错误的值 [77]
。任何人都知道我如何更新 queryItems
以便在 excludeIds
发生变化时进行更新?
最终通过使用
React.useRef
中的 Select
解决了这个问题。 useRef
允许我们跟踪渲染之间可用的 queryItems
的可变引用。每次 queryItems
发生变化时,useEffect
都会捕获该变化,并且我们能够将其存储在搜索功能中使用的引用中。
const Select = ({ queryItems, excludeIds, addItem }) => {
const [items, setItems] = useState(dummyItems);
const searchResults = (value) => {
return queryItems(items);
}
const queryItemsRef = React.useRef(queryItems);
React.useEffect(() => {
queryItemsRef.current = queryItems;
}, [queryItems]);
return (
<SearchSelect search={searchResults} onItemSelect={(item) => addItem(item)} />
);
};