使用React钩子如何一起更新2个钩子,但彼此使用prevState

时间:2018-11-24 13:54:51

标签: javascript reactjs react-hooks

在下面的代码中,当我调用protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dial("000000"); } }); } private void dial(final String phoneNumber) { startActivity(new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phoneNumber, null))); } 时,我同时更新了2个钩子。

func containsPeer(peers []fab.Peer, peer fab.Peer) bool { for _, p := range peers { if p.URL() == peer.URL() { return true } } return false } peers[3].url = localhost:7051 peer.url = peer0.org1.example.com:7051 是一个简单的布尔值,但是_toggleSearch钩子必须以先前的toggleSearchIsVisible状态通过。

如何确定传入的其他状态尚未更新?还是我应该如何重组一切?以前使用setActiveFilter可以轻松地通过以前的状态。

searchIsVisible

我现在已经解决了这个问题

setState

任何其他建议,谢谢!

2 个答案:

答案 0 :(得分:1)

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

这里是一个例子:

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

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

您可以看到我也将[searchIsVisible]传递给了useEffect钩子以优化性能。

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


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

我希望这会有所帮助。

注意:

我还根据您的条件切换了SHOW_ALLSHOW_SEARCH的顺序,因为当SHOW_SEARCHsearchIsVisible时似乎应该显示false,并且SHOW_ALLsearchIsVisible时应显示true,但是如果不是这种情况,只需将顺序切换回去。

答案 1 :(得分:0)

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

在以下示例中,我演示了如何使用activeFiltersearchIsVisible作为要保留的单个状态。

如果保留activeFilter,则searchIsVisible的值从导出,反之亦然。关键是根据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>