XState Series: Temperature Converter
Tags: xstate, tutorial, javascript
Published: 2020-03-14 22:21:20

TL;DR
If you just want the code/project to run locally -- https://github.com/JacobMGEvans/finite-state-machine/tree/master/fsm-projects/temperature

Since I actually ran into my first couple of roadblocks ***see any GIF of someone hitting their computer for reference*** Now I put myself in the situation because I wanted to hurt a little after the quick win with the XState Counter project. I was thinking to myself, "Hell yeah, I got this it's all gonna click just read the docs" Well I also knew to humble myself and not to copy-paste tutorial code, thinking I am learning a whole lot(learned that the hard way at my Coding Bootcamp. 

Ok, so I still copy-pasted the Machine from the Temperature Converter 7GUI list. However, I specifically avoided other code implementation... What did I come up with it looked a little something like 
```javascript
import React from "react";
import { useMachine } from "@xstate/react";
import { temperatureMachine } from "../../machines/temperature-machine";

const sStyle = { fontSize: 20 };
export default function Temperature() {
  const [current, send] = useMachine(temperatureMachine);

  return (
    <>
      <input
        type="number"
        style={sStyle}
        onChange={e => send(`FAHRENHEIT`, { value: e.target.value })}
      />
      <span>{current.context.F}˚F</span>
      <br />
      <input
        type="number"
        style={sStyle}
        onChange={e => send(`CELSIUS`, { value: e.target.value })}
      />
      <span>{current.context.C}˚C</span>
    </>
  );
}
```
Now some of you might be noticing something missing right away and mind you that is very astute. It took me hours to figure out what I was doing wrong. Not sure why but my brain had completely disassociated React's local state implementation from XState implementation in the component. 
Once I remedied that I ended up with this instead: 
![return (
    <>
      <input
        type="number"
        value={state.context.F}
        style={sStyle}
        onChange={e => send(`FAHRENHEIT`, { value: e.target.value })}
      />
      <span>˚F</span>
      <br />
      <input
        type="number"
        value={state.context.C}
        style={sStyle}
        onChange={e => send(`CELSIUS`, { value: e.target.value })}
      />
      <span>˚C</span>
    </>
  );](https://dev-to-uploads.s3.amazonaws.com/i/lhz5lobyesfho63pf0p4.png)

Keep in mind I changed the "current" to "state" that was for my own mental context not because it somehow affected the implementation, but helped me to better understand the implementation. It could be "UnicornRainbow" for all the component cares.

Alright, so we are done with this Temp Project right!? No. 
**🚧🚦Stop if purely interested in XState implementation🚧🚦**
While I was testing with browser console open I noticed something, React was complaining, "What's wrong React, did I do something" **_React laughs in error message_** "Uncontrolled input is switching to controlled" I know again some of you are like "I KNOW!"... 
I wish you were sitting next to me when it happened lol 😅😆

I investigate... I think it potentially XState w/ React related and reach out to David, who confirms its a React thing and dig deeper. So I dig real deep and after some time in existential crisis I figured it out. 
It actually has to do with that original copy-paste of the Machine 😅
```javascript
import { Machine, assign } from "xstate";

export const temperatureMachine = Machine({
  initial: `active`,
  context: { C: undefined, F: undefined },
  states: {
    active: {
      on: {
        CELSIUS: {
          actions: assign({
            C: (_, event) => event.value,
            F: (_, event) => (event.value ? +event.value * (9 / 5) + 32 : ``)
          })
        },
        FAHRENHEIT: {
          actions: assign({
            C: (_, event) => (event.value ? (+event.value - 32) * (5 / 9) : ``),
            F: (_, event) => event.value
          })
        }
      }
    }
  }
});
```
 So some of you might see it now, which took me quite some time to notice. Well, "value" in React expects a type and apparently uses that type has been passed for the input to be controlled. 
so this:
```javascript
context: { C: undefined, F: undefined },
```
was making that input think it was uncontrolled, so maybe expecting a ref to change it from undefined or something, instead, I was updating the "value" attribute with state.context switching it to controlled. 
The fix was just a quick change to the initial values. 
```javascript
context: { C: ``, F: `` },
```
I think this was also a more difficult challenge because I was still disassociating XState implementation from the React behavior and component for some reason. I think this exercise helped to concrete XState is a means of implementation, not a replacement.