0
votes

I wanted to setState with react hooks usestate.

First I tried. but it not worked.

const [action, setAction] = useState(null);
...
<button onClick={()=>{
  setAction(()=>{console.log('hi')})
}}>test</button>

Second. It worked.

const [action, setAction] = useState({action: null});
...
<button onClick={()=>{
  setAction({
    action:()=>{
      console.log('hi')
    }
  })}
}>test</button>

Because if I set function directly, the state changed to undefined.

So I pass the function with object type.

But I want to know if there is another way to set state with function.

3
Why is a function state variable? const [state, useState] = useState() is problematic on its ownSinan Yaman
please don't use reserve functions like useState and state try changing it to some other namesJibin Francis
@SinanYaman I need function state variable because, I should change action on a button by some other changes. Is this appropriate answer with your question?wantyouring

3 Answers

1
votes

The issue with your approach is that you are not returning the function in the first place. you are just using the setAction callback to console.log('hi').

<button onClick={()=>{
  setAction(()=>{console.log('hi')})
}} />

To fix this issue you need to return a new function in the callback function.

<button onClick={()=>{
  setAction(() => () => {console.log('hi')})
}} />
1
votes

I think what you need is useRef, not useState...!

As documented, if you passed a function to useState, it will set the state to the value it gets after executing the passed function...!

So setAction(()=>{console.log('hi')}) means set the action state to the result of executing this function ()=>{console.log('hi')}, that gives you undefined (because ()=>{console.log('hi')} returns nothing).

If you need to store a function, maybe try this...?

import { useRef } from 'react'

// ... other code

const functionRef = useRef(null)

<button
  onClick={() => functionRef.current = () => console.log('hi')}
/>

// ...
0
votes

I think the problem is with <button />, it should be <button></button>. Here's a JSFiddle where your code is working

const useState = React.useState;

const App = () => {

    const [action, setAction] = useState(null);

    return (
      <button onClick={()=>{
            setAction(()=>{console.log('hi')})
        }}>Click me!</button>

    );

}

const render = () => ReactDOM.render(
  <App/>,
  document.getElementById('app')
);

render();
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/0.14.0/react-dom.min.js"></script>
<div id="app">
  <!-- This element's contents will be replaced with your component. -->
</div>