简体   繁体   中英

useState hook with callback

The app below has two buttons, both changing the same state, but has different callbacks.

My question is how do I achieve the same result with hooks with functional components? I have seen some custom hooks like useStatewithCallback , which is essentially the same as below

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

The problem with that approach is that useEffect only knows if counter has changed, but not what changed it. If I were to do that, then the same side effect will fire (aka same callback).

What I need is something like this

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

So the only think I can think of right now is to add states to the buttons, then rewrite the useEffects.

Is there an easier way?

 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>

Here is what you should do:

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>
  );
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM