0

Why doesn't this function work like the useState() hook from react?

const myState = val => {
  let value = {
    val,
    set setVal(newVal) {
      this.val = newVal;
    }
  };

  const setValue = newVal => {
    value.setVal = newVal;
  }

  return [value.val, setValue];
}

const [myVal, setMyVal] = myState("initial value");

console.log(myVal);
setMyVal("updated value");
console.log(myVal);

Expected output:

initial value
updated value

Actual output:

initial value
initial value
Glen Carpenter
  • 392
  • 2
  • 9
  • don't you need to do something like `value.setValue("updated value");`? – Rick Jun 22 '20 at 19:57
  • Sorry, had to update the code snippet, there was a typo – Glen Carpenter Jun 22 '20 at 20:00
  • Because it has no way of telling React "hey something changed and you need to re-render"? – Jared Smith Jun 22 '20 at 20:01
  • This is not using React, just vanilla JS trying to mimic the useState() hook – Glen Carpenter Jun 22 '20 at 20:02
  • Yeah I get that, but *the whole point* of `useState` is that React automatically renders the changes for you, and only the things actually impacted by the change. So if that's not what you care about, then it's not clear what your question actually is. – Jared Smith Jun 22 '20 at 20:03
  • 2
    I'm not real familiar with this type of coding, but why would you define a variable to be a const, and then expect it's value to change? that doesn't seem right. – Rick Jun 22 '20 at 20:03
  • @Rick const data structures are still mutable, you just can't rebind the name to a different data structure. – Jared Smith Jun 22 '20 at 20:04
  • 1
    @Rick Yes, that's a point most people miss. A const cannot change its value. Just because its part of a state hook doesn't change that fact. Instead, react sets the const to the updated value on the *next* render, so the const never changes values, but is instead destroyed and re-created. – Brian Thompson Jun 22 '20 at 20:05
  • I understand why the initial value works, however I'm not sure why the setter doesn't work. I am wondering if there are multiple instances of myState() being created, and I just don't understand why? – Glen Carpenter Jun 22 '20 at 20:08
  • 1
    There's *a lot* of things wrong in that code, but even if you make it work exactly like useState in React, it would still print "initial value" twice because that's what React's useState would also do. – Guy Incognito Jun 22 '20 at 20:09
  • @GlenCarpenter You can't just mimic the `useState` hook in isolation. If you could there would be libraries out there that do it for you. State management is a big part of what react does and the purpose it serves. Don't reinvent the wheel. – Brian Thompson Jun 22 '20 at 20:10
  • 2
    React hooks are not this straight forward. They have complex implementations. For starters, the function component is executed again, the variables are recreated with new values after `setValue` is called – adiga Jun 22 '20 at 20:11
  • @BrianThompson not trying to reinvent anything, just trying to get a better understanding of the inner workings – Glen Carpenter Jun 22 '20 at 20:12
  • 1
    [Here's a simplified version](https://stackoverflow.com/a/53895655/3082296) – adiga Jun 22 '20 at 20:18
  • You assign `myVal` only once and don't mutate it so it doesn't change. – HMR Jun 22 '20 at 20:25
  • @adiga thanks for the link! I think I get it now... in the React library it is storing the 'value' ouside of the function that mutates it, so you get the updated value between calls. – Glen Carpenter Jun 22 '20 at 20:44
  • Of course the values are stored outside. In classes, you store the data in `this.state` and every instance of the class component gets it's own state property. A function component is just a normal function that returns some jsx. It can't *hold* any data. It needs to be executed again to re-render that jsx. `React.useState` will keeps track of data for each *fake-instance* of the function. `useState` function could be used in multiple functional components. A single functional component could be used multiple times. – adiga Jun 23 '20 at 18:30

0 Answers0