【发布时间】:2020-10-31 12:46:21
【问题描述】:
目前我正在做一个项目,我正在使用 react 和 redux 来构建它。
场景
-
有一个切换按钮,可以在组队列和我的队列之间切换。这两个都将命中一个 api 并加载数据(票证列表)。[即2 个独立的实体]
-
现在有一个搜索框,会根据我输入的值给出结果。我添加了“Delay functionality”,即 2 秒后 onChange 事件将触发,并将向所有减速器发送一个操作。
问题
假设我在组队列下搜索一个值(68),它工作正常。现在,如果我切换到我的队列,SearchBox 值应该为 null。但它显示为 68 正如我所说,两个队列都是独立的主体,如果我切换,searchBox 的值应该消失,但不是。
原因
-
我正在存储搜索框值和计时器的状态,以设置 2 秒后键入时的值,并且在我键入的每个字符上,将调用 setTimeOut 和 clearTimeOut 以适应 delay functionality。
-
因此,我的 React SearchBox 组件中有一个状态,一旦我输入并停留 2 秒,它就会通过 useEffect/ComponentDidUpdate 调度操作。
-
我决定在组件内部设置一个状态,因为我不想对每个用户类型的字符触发操作。只有预期的搜索值 Redux 应该存储。
我尝试过的事情
-
我尝试使用 getDerivedStateFromProps,但由于我需要使用 SetState 及其异步,它不反映当前值。
-
我添加了 2 个功能(onChange 和 OnEnter)。使用 OnEnter,我认为它会起作用,因为我可以将 redux 存储的值和操作传递给输入的值和 OnEnter 属性。 [我没试过]
-
但我想要延迟功能。任何人都可以提出替代方案吗?
代码
1.搜索组件
import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { filterAction } from "../../actions";
import "./search.css";
const WAIT_INTERVAL = 2000;
const ENTER_KEY = 13;
const Search = (props) => {
console.log("search", props.value);
let [value, setValue] = useState(props.value);
let [timer, setTimer] = useState(0);
useEffect(() => {
setTimer(
setTimeout(() => {
if (timer) props.filterAction("SEARCH_FILTER", value);
}, WAIT_INTERVAL)
);
return () => clearTimeout(timer);
}, [value]);
const handleKeyDown = (event) => {
if (event.keyCode === ENTER_KEY) {
clearTimeout(timer);
props.searchAction("SEARCH_FILTER", value);
}
};
// GETDERIVEDSTATEFROMPROPS
// if (props.value !== value) {
// setValue("");
// // console.log("check2", props.value, value);
// }
return (
<input
className="search-box"
type="search"
placeholder="Search any Request Id/ Email Id..."
aria-label="Search"
value={value}
onChange={(e) => setValue(e.target.value)}
onKeyDown={handleKeyDown}
></input>
);
};
const mapStateToProps = (store) => ({
value: store.filterValues.searchFilter,
});
export default connect(mapStateToProps, { filterAction })(Search);
- Redux Redcuer(FilterReducer)——工作正常,即在切换时,searchValue 被清空('')。
export const filterReducer = (filterValues = {}, action) => {
switch (action.type) {
case "TOGGLE_QUEUE":
return {
order: [],
tileFilter: action.payload.tileType,
searchFilter: "",
buttonFilter: {},
timelineFilter: "all",
};
case "SEARCH_FILTER":
let arr = [...filterValues.order];
arr.push("SEARCH_FILTER");
let ob = {
...filterValues,
searchFilter: action.payload.value,
order: arr,
};
return ob;
}
return filterValues;
};
如果您有任何解决方案,请告诉我。
编辑 1 我在 UseEffect 上尝试了 props.value,现在 搜索本身不起作用..
useEffect(() => {
// setValue(props.value); // not working
setTimer(
setTimeout(() => {
if (timer) props.filterAction("SEARCH_FILTER", value);
}, WAIT_INTERVAL)
);
setValue(props.value); // not working
return () => clearTimeout(timer);
}, [props.value]);
编辑2
我按照 Sabbit 的建议添加了一个单独的 useffect,但如果我输入 68,搜索功能将在 6 上调用并交替输入值 (68)。
useEffect(() => {
setTimer(
setTimeout(() => {
if (timer && value.length > 0)
props.filterAction("SEARCH_FILTER", value);
}, WAIT_INTERVAL)
);
return () => clearTimeout(timer);
}, [value]);
useEffect(() => {
if (value !== props.value) setValue(props.value);
}, [props.value]);
【问题讨论】:
标签: javascript reactjs redux ecmascript-6 react-redux