0

How does this work?

I want to declare a variable inside of a react component class and use it in several different areas in my app.

The attempt looks like this:

class ColorPick extends React.Component {
  colorInput;

  constructor(props) {
    super(props);
    this.state = {
      color: "Let's pick a color"
    };
  }

  // use this many times in my app
  colorInput = document.getElementById("colorInput").value;

  changeColor(event) {
    this.setState({
      color: "#" + event.target.value,
      backgroundColor: "#" + event.target.value
    });

    if (colorInput === "") {
      this.setState({
        color: "Let's pick a color",
        backgroundColor: "#fff"
      });
    }
  }
}

What happens is I get this error:

Error in ./src/components/colorpicker.jsx Syntax error: Unexpected token (12:8)

10 | } 11 |

12 | var colorInput = document.getElementById('colorInput').value; | ^ 13 | 14 | changeColor(event) { 15 | this.setState({

@ ./src/index.js 29:19-54

I don't understand why this happens, and I can't find any documents that explain this clearly.

How to declare global variables in React JS

So I did:

global.js:

global.colorInput = colorInput;

colorpicker.js:

import React, { Component } from 'react';
import Global from './global'

class ColorPick extends React.Component {

    constructor(props) {
      super(props);
      this.state = {
        color: "Let's pick a color"
      };
    }

    var colorInput = document.getElementById('colorInput').value;

    changeColor(event) {
      this.setState({
        color: '#' + event.target.value,
        backgroundColor: '#' + event.target.value
      });

      if (colorInput === '') {
        this.setState({
          color: "Let's pick a color",
          backgroundColor: "#fff",
      });
    }
   }

I still get the same error. Why?

How do I create a globally accessible variable in React JS

Doesn't quite answer my question in the context I'm looking for.

How can I declare a variable inside of a react class/component and reuse it? How does that work?

guzmonne
  • 2,490
  • 1
  • 16
  • 22
kawnah
  • 3,204
  • 8
  • 53
  • 103
  • 1
    It seems like what you are trying to do might be easier if you stored the colorInput value in a parent component. I think this is the best practice; https://reactjs.org/docs/lifting-state-up.html – Andrew Seymour Jul 25 '19 at 15:30
  • put `var colorInput =` in the constructor – Daniel Lizik Jul 25 '19 at 15:30
  • in second approach , you are still getting erro because you still using same variable declaration instead of using Global.colorInput – Naga Sai A Jul 25 '19 at 15:31
  • Can someone please explain why in React this error happens? – kawnah Jul 25 '19 at 15:33
  • 3
    This isn't a React thing — it's a JavaScript thing. The body of a class is different from the body of a function. You can't put arbitrary expressions in the body of a class. – Bryan Downing Jul 25 '19 at 15:35
  • @DanielLizik `20:11 error 'colorInput' is not defined no-undef` – kawnah Jul 25 '19 at 15:38
  • @kawnah `var colorInput = document.getElementById('colorInput').value;` needs to be `global.colorInput = document.getElementById('colorInput').value` – Andrew Seymour Jul 25 '19 at 15:43

3 Answers3

3

You have a problem with your ColorPick component: you are trying to define a class field declaration using the var keyword. This is why you are getting a syntax error. Also, field declarationsin classes are an experimental feature. Meaning, you'll have to use some pre-processor to transpile your code to ES5, so it works on browsers that don't support this feature.

Take a look at the Fields declarations documentation for more information.

And, instead of assigning it to the document.getElementById('colorInput').value at the field declaration you should do it inside the constructor. Then you'll have the most updated value. Here is how I would re-write your component:

class ColorPick extends React.Component {
  colorInput;

  constructor(props) {
    super(props);
    this.state = {
      color: "Let's pick a color"
    };
    this.colorInput = document.getElementById("colorInput").value;
  }

  changeColor(event) {
    this.setState({
      color: "#" + event.target.value,
      backgroundColor: "#" + event.target.value
    });

    if (colorInput === "") {
      this.setState({
        color: "Let's pick a color",
        backgroundColor: "#fff"
      });
    }
  }
}

Now, there are several ways to share data between components without needing to define variables in the Global Scope. See React's "Lifting State Up" documentation page to some introduction of how you can deal with this. Then you can also try something like React Context, or Redux.

If you want to declare something in the Global Scope you can use the window object.

window.myGlobalVar = '#FFF'

You are going to have to check how it is mutated throughout the app's lifecycle, so I suggest you try other alternatives first.

guzmonne
  • 2,490
  • 1
  • 16
  • 22
  • Not a JavaScrip/React fan I see. You'll get used to it :D – guzmonne Jul 25 '19 at 15:48
  • it looks like colorInput after I implemented your example is still undefined – kawnah Jul 25 '19 at 15:52
  • Well, I didn't try to make the code work, since for that I would need more knowledge of your app. I just tried to point out an error and suggest some alternatives. Using them you should refactor your code. There may be many reasons as to why the value of `colorInput` is `undefined`. – guzmonne Jul 25 '19 at 15:54
0

Take a look at context: https://reactjs.org/docs/context.html. In react your issue can be managed with that.

flo
  • 559
  • 1
  • 8
  • 26
  • okay, but why in my example specifically do I get that error? Why can't I simply declare a variable? – kawnah Jul 25 '19 at 15:33
  • 3
    [An answer should actually contain an answer.](https://meta.stackexchange.com/q/8231/254800) Not just directions towards the answer. – Emile Bergeron Jul 25 '19 at 15:34
  • Hmmm. I'm trying to do this like `const colorInput = React.createContext('');` and the errors dissapear but my webpage is completely blank - why would that be? – kawnah Jul 25 '19 at 15:42
0

To define a global variable in ReactJS you can create a Context, so you can pass around in a React App. you can define your variable like this:

GlobalColor.js:

import React from 'react'

const GlobalColor = React.createContext({});
export const ColorProvider = GlobalColor.Provider;
export const ColorConsumer = GlobalColor.Consumer;
export default GlobalColor;

Here we have a Provider component which provides the value and Consumer component which is consuming (using) the value.

Provider code might be something like this:

ColorPickerProvider.js:

import React from 'react'
import ColorPickerConsumer from './ColorPickerConsumer'
import { ColorProvider } from './GlobalColor'

function ColorPicker() {
  const color = 'blue'
  return (
    <ColorProvider value={color}>
      <ColorPickerConsumer />
    </ColorProvider >
  )
}

Now any child has access to the color.

In the next step you can use the code below where you want to use(consume) the color value:

ColorPickerConsumer.js:

import React, { Component } from "react";
import GlobalColor from "./GlobalColor";

class ColorPickerConsumer extends Component {
  static contextType = GlobalColor;
  render() {
    const color = this.context;
    return <div>{color}</div>;
  }
}
export default ColorPickerConsumer;