0

在下面的代码中,当我调用时,我_toggleSearch同时更新了 2 个钩子。

toggleSearchIsVisible是一个简单的布尔值,但是,setActiveFilter钩子必须在前一个searchIsVisible状态中传递。

我如何确定传入时其他状态尚未更新?或者我应该如何重组一切?以前setState我可以很容易地通过以前的状态。

const [activeFilter, setActiveFilter] = useState('SHOW_ALL');
const [searchIsVisible, toggleSearchIsVisible] = useState(false);

const _toggleSearch = () => {
  setActiveFilter(searchIsVisible ? 'SHOW_SEARCH' : 'SHOW_ALL');
  toggleSearchIsVisible(!searchIsVisible);
};

我现在已经这样做了:

const _toggleSearch = () => {
  if (searchIsActive) {
    setActiveFilter('SHOW_ALL');
    toggleSearchIsActive(false);
  } else {
    setActiveFilter('SHOW_SEARCH');
    toggleSearchIsActive(true);
    updateSearchValue('');
  }
};

任何其他建议表示赞赏!

4

2 回答 2

1

尝试使用钩子来处理切换布尔值useEffect的副作用。searchIsVisible

这是一个例子:

const _toggleSearch = () => {
  toggleSearchIsVisible(!searchIsVisible);
};

useEffect(() => {
  setActiveFilter(searchIsVisible ? 'SHOW_ALL' : 'SHOW_SEARCH');
}, [searchIsVisible]);

可以看到我也传给[searchIsVisible]useEffect钩子来优化性能。

这将确保useEffect仅在searchIsVisible更新时触发:https ://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects


这是一个演示:https ://codesandbox.io/s/l2901jr68l

我希望这有帮助。

笔记:

此外,我在您的条件中切换了SHOW_ALLand的顺序SHOW_SEARCH,因为它似乎SHOW_SEARCH应该在searchIsVisibleis时显示false,并且SHOW_ALL应该在searchIsVisibleis时显示true,但如果不是这种情况,只需将顺序切换回来。

于 2018-11-24T15:01:04.340 回答
0

如果遇到同步两个状态的情况,请退后一步,看看其中一个状态是否可以从另一个导出。在这种情况下,您所拥有的两种状态似乎本质上是相关的,其中一种状态确实可以从另一种中派生出来。所以你实际上不需要两个状态值,你只需要一个。派生状态不应该是状态的一部分,因为这会导致状态重复,然后您必须同步状态值,这就是您在问题中提出的问题。

在下面的示例中,我演示了如何使用其中之一activeFiltersearchIsVisible作为单个状态来保留。

如果您保留activeFilter,则 的值searchIsVisible是从 the 派生的,反之亦然。关键是searchIsVisible根据 的值进行设置activeFilter

activeFilter作为国家

const App = () => {
  const [activeFilter, setActiveFilter] = React.useState('SHOW_ALL');
  const searchIsVisible = activeFilter !== 'SHOW_ALL';

  const _toggleSearch = () => {
    setActiveFilter(activeFilter === 'SHOW_ALL' ? 'SHOW_SEARCH' : 'SHOW_ALL');
  };

  return (
    <div>
      <p>Active Filter: {activeFilter}</p>
      <button onClick={_toggleSearch}>Toggle Search</button>
      {searchIsVisible && <div>
        <input placeholder="Search" />
      </div>}
    </div>
  );
};

ReactDOM.render(<App />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>

searchIsVisible作为国家

const App = () => {
  const [searchIsVisible, setSearchIsVisible] = React.useState(false);
  const activeFilter = searchIsVisible ? 'SHOW_SEARCH' : 'SHOW_ALL';

  const _toggleSearch = () => {
    setSearchIsVisible(!searchIsVisible);
  };

  return (
    <div>
      <p>Active Filter: {activeFilter}</p>
      <button onClick={_toggleSearch}>Toggle Search</button>
      {searchIsVisible && <div>
        <input placeholder="Search" />
      </div>}
    </div>
  );
};

ReactDOM.render(<App />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>

于 2018-11-25T04:40:10.247 回答