【问题标题】:on toggling, Search Box value is not getting updated [React + Redux]切换时,搜索框值未更新 [React + Redux]
【发布时间】:2020-10-31 12:46:21
【问题描述】:

目前我正在做一个项目,我正在使用 react 和 redux 来构建它。

场景

  1. 有一个切换按钮,可以在组队列和我的队列之间切换。这两个都将命中一个 api 并加载数据(票证列表)。[即2 个独立的实体]

  2. 现在有一个搜索框,会根据我输入的值给出结果。我添加了“Delay functionality”,即 2 秒后 onChange 事件将触发,并将向所有减速器发送一个操作。

问题

假设我在组队列下搜索一个值(68),它工作正常。现在,如果我切换到我的队列,SearchBox 值应该为 null。但它显示为 68 正如我所说,两个队列都是独立的主体,如果我切换,searchBox 的值应该消失,但不是。

原因

  1. 我正在存储搜索框值和计时器的状态,以设置 2 秒后键入时的值,并且在我键入的每个字符上,将调用 setTimeOut 和 clearTimeOut 以适应 delay functionality

  2. 因此,我的 React SearchBox 组件中有一个状态,一旦我输入并停留 2 秒,它就会通过 useEffect/ComponentDidUpdate 调度操作。

  3. 我决定在组件内部设置一个状态,因为我不想对每个用户类型的字符触发操作。只有预期的搜索值 Redux 应该存储。

我尝试过的事情

  1. 我尝试使用 getDerivedStateFromProps,但由于我需要使用 SetState 及其异步,它不反映当前值。

  2. 我添加了 2 个功能(onChange 和 OnEnter)。使用 OnEnter,我认为它会起作用,因为我可以将 redux 存储的值和操作传递给输入的值和 OnEnter 属性。 [我没试过]

  3. 但我想要延迟功能。任何人都可以提出替代方案吗?

代码

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);
  1. 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


    【解决方案1】:

    您是否尝试过为 props.value 使用另一个 useEffect?

    useEffect(() => {
      setTimer(
        setTimeout(() => {
           if (timer && value.length > 0) props.filterAction("SEARCH_FILTER", value);
        }, WAIT_INTERVAL)
      );
      return () => clearTimeout(timer);
    }, [value]);
    
    useEffect(() => {
       setValue(props.value);
    }, [props.value]);
    

    这将在每次更改 props.value 时更新 state 中的值。我相信来自 reducer 的 searchValue 是通过 props 传递给 Search 组件的。

    更新:我已将执行props.filterAction("SEARCH_FILTER", value) 的条件从if(timer) 更新为if(timer &amp;&amp; value.length &gt; 0)。我们需要这样做,因为每次 props 更改时,我们都会将 value 设置为状态,并且我们使用了 useEffect 取决于 value 状态的更改。这就是它使用空字符串搜索的原因。我们需要确保搜索不会发生,除非我们在输入字段中有内容。

    【讨论】:

    • 我试过了,现在搜索没有发生..请参阅edit1部分
    • 可以创建多个useEffect。您不应该更新以前的 useEffect,只需在其下添加另一个 useEffect。
    • 我已经更新了我的代码。请看那个。你之前的 useEffect 应该是原来的样子。之后只需添加另一个 useEffect 方法调用即可。
    • 你没有在第二个 useEffect 中声明任何计时器,所以你不应该清除那里的任何东西。
    • 嗨,不......虽然它在每次切换时都会清除值,但搜索每秒都在发生......就像它每秒自动调用一个空值和输入值
    猜你喜欢
    • 2016-07-14
    • 1970-01-01
    • 2019-06-06
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    相关资源
    最近更新 更多