带有回调的useState钩子

时间:2020-03-10 20:21:19

标签: javascript reactjs react-hooks

下面的应用程序有两个按钮,它们都更改相同的状态,但是具有不同的回调。

我的问题是,如何使用具有功能组件的挂钩实现相同的结果?我已经看到了一些useStatewithCallback之类的自定义钩子,该钩子基本上与下面的相同

useEffect(()=>{
   /*some side effect here*/
}[counter])

该方法的问题在于useEffect仅知道counter是否已更改,但不知道更改了什么。如果我要这样做,则会产生相同的副作用(也称为相同的回调)。

我需要的是这样的东西

useEffect(()=>{
   /*if first button clicked, run first side effect*/
   /*if second button clicked, run second side effect*/
}[counter])

所以我现在唯一能想到的就是将状态添加到按钮,然后重写useEffects。

有没有更简单的方法?

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {counter: 0};
  }
  
  clickFirst = ()=>{
    this.setState({counter:this.state.counter + 1},
    ()=>{
      console.log('first button clicked')
      console.log(`the counter is now ${this.state.counter}`)
    })
  }
  
  clickSecond = ()=>{
    this.setState({counter:this.state.counter + 1},
    ()=>{
      console.log('second button clicked')
      console.log(`the counter is now ${this.state.counter}`)
    })
  }
  
  render(){
    return(
      <div>
        <button onClick={this.clickFirst}>{this.state.counter}</button>
        <button onClick={this.clickSecond}>{this.state.counter}</button>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

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

1 个答案:

答案 0 :(得分:0)

这是您应该做的:

const App = () => {
  const [ counter, setCounter ] = useState(0);
  const [ buttonClicked, setButtonClicked ] = useState(null);

  useEffect(
    () => {
      if (buttonClicked == "firstButton") {
        // do some stuff
      } else if (buttonClicked == "secondButton") {
        // do some stuff
      }
    },
    [ buttonClicked, counter ]
  );

  clickFirst = () => {
    setCounter(counter + 1);
    setButtonClicked("firstButton");
  };

  clickSecond = () => {
    setCounter(counter + 1);
    setButtonClicked("secondButton");
  };

  return (
    <div>
      <button onClick={clickFirst}>{counter}</button>
      <button onClick={clickSecond}>{counter}</button>
    </div>
  );
};