我有一个由ParentComponent和HelpSearchWindow组成的React应用程序。在ParentComponent的页面上,有一个按钮,可以让你打开一个包含HelpSearchWindow的窗口。HelpSearchWindow有一个输入字段和一个搜索按钮。当键入输入并单击搜索按钮时,运行搜索并将结果显示到窗口的表中。可以关闭窗口。我设置了react.useEffect()与依赖项[documentationIndexState.searchTerm]
挂钩,以便仅在searchTerm改变时才运行搜索功能。
但是,窗口的行为并不像我预期的那样。**因为useEffect()在窗口关闭之后每次打开窗口时被调用,则它将再次运行搜索,而不管依赖性数组中的searchTerm是否相同。**因此,我又加了一个州 prop (prevSearchTerm)来存储最后搜索的项。这样,如果窗口被打开和关闭多次而没有设置新的searchTerm,没有重复的搜索运行。
我的问题是,是否有更惯用/React式的方法来实现这一点?也欢迎使用任何其他代码格式化指针
import {
setSearchTerm,
} from 'documentationIndex.store';
interface Props {
searchInput: string;
setSearchInput: (searchInput: string) => void;
prevSearchTerm: string;
setPrevSearchTerm: (searchInput: string) => void;
}
export const HelpSearchWindow: React.FC<Props> = props => {
const documentationIndexState = useSelector((store: StoreState) => store.documentationIndex);
const dispatch = useDispatch();
// Only run search if searchTerm changes
React.useEffect(() => {
async function asyncWrapper() {
if (!documentationIndexState.indexExists) {
// do some await stuff (need asyncWrapper because of this)
}
if (props.prevSearchTerm !== documentationIndexState.searchTerm) {
// searching for a term different than the previous searchTerm so run search
// store most recently used searchTerm as the prevSearchTerm
props.setPrevSearchTerm(props.searchInput);
}
}
asyncWrapper();
}, [documentationIndexState.searchTerm]);
return (
<input
value={props.searchInput}
onChange={e => props.setSearchInput(e.target.value)}
/>
<button
onClick={e => {
e.preventDefault();
dispatch(setSearchTerm(props.searchInput));
}}
>
Search
</button>
<SearchTable
rows={documentationIndexState.searchResults}
/>
);
};
//--------- Parent Component----------------------------------------
const ParentComponent = React.memo<{}>(({}) => {
const [searchInput, setSearchInput] = React.useState(''); // value inside input box
const [prevSearchTerm, setPrevSearchTerm] = React.useState(''); // tracks last searched thing
return(
<HelpSearchWindow
searchInput={searchInput}
setSearchInput={setSearchInput}
prevSearchTerm={prevSearchTerm}
setPrevSearchTerm={setPrevSearchTerm}
/>
);
});
2条答案
按热度按时间ctzwtxfj1#
从给定的上下文来看,useEffevt钩子的使用是多余的。您应该简单地使用一个单击处理函数并附加到按钮上。
click处理程序将把搜索项存储在组件本地,同时检查新的输入值是否不同,如果是,将更新状态并调用API。
jmo0nnb32#
我假设您正在使用react-redux或react-redux/工具包
'createSelector'是来自reselect库的实用程序函数,它允许您创建“记忆”选择器,以便在Redux应用程序中进行有效的数据检索。记忆选择器是一个函数,它将为同一组输入返回相同的结果,如果输入没有更改,则无需重新计算结果。
下面是如何在Redux应用程序中使用“createSelector”的示例:
在本例中,我们有两个选择器:getUsers选择状态的用户切片,getUserId接受第二个参数(组件的属性)并返回userId属性。
createSelector函数以一个输入选择器数组和一个transform函数作为参数,transform函数接收输入选择器的值作为参数,并返回转换后的数据。
在本例中,getUser选择器是一个记忆选择器,它从users数组返回具有指定userId的用户对象。如果users或userId值未更改,getUser将返回相同的结果,而无需重新计算。
然后可以在组件中使用getUser选择器,如下所示: