9

I have a global variable that will change often. Let's say it is stored in window.something. In react I need this change to be reflected in the component as well as in its state.

Example code:

class Example extends React.Component {

  constructor(props) {
        super(props);
        this.state = { something: '1'}
    }


  render() {
     return (
      <div>
      <input value={window.something}
             onChange={event => {this.setState({'something': event.target.value})}} 
      />
      </div>
    )
  }
}

However the value gets set only for the first time and there is no change as the variable gets updated.

sjishan
  • 3,392
  • 9
  • 29
  • 53
  • Do you want to use the `window.something` value only for the first time? – salman.zare Mar 28 '18 at 05:46
  • 2
    What caused the global variable to change? – Steven Mar 28 '18 at 05:57
  • Try changing the fat arrow function to normal function. Because, using 'this' inside fat arrow function does not work as expected and it refers to the outer object – rahul_sann Mar 28 '18 at 06:22
  • it should be a `prop`, something like `` Then in your component `const MyComponent = ({something}) => { React.useEffect(()=>{ // do something when something changes return () => {} ,[something]}) ... }` – Rafael Mora Oct 14 '19 at 16:57

3 Answers3

1

This won't be triggered by a change to a storage object. If you have access to the process that triggered the change, then have it call an update to state. If you don't have access, maybe you could poll for the change every so often.

Personally, I just get it from storage on pages that I need it, or add it to state and use that for the rest of the session.

componentWillMount = () => {
    const foo = JSON.parse(sessionStorage.getItem('foo'));
    const bar = JSON.parse(sessionStorage.getItem('bar'));

    if (!isEmpty(foo) && !isEmpty(bar)) {
        this.props.setFoo(foo);
        this.props.setBar(bar);
    } 
}

Here is a link explaining how to set an event listener on a browser's localStorage.

Jay Jordan
  • 643
  • 4
  • 16
-1

Something like this?

window.something='1234';

  class Example extends React.Component {

    constructor(props) {
      super(props);
      this.state = { something: window.something}
    }

    render() {
      return (
        <div>
          <input defaultValue={window.something}
                 value={this.state.something}
                 onChange={event => {this.setState({'something': event.target.value})}}
          />
        </div>
      )
    }
  }
salman.zare
  • 649
  • 5
  • 8
-1

There are 2 approaches in your case:

  1. Whenever the global variable change, re-render the Example component. This is a costly operation.
  2. Example component should listen for a change in window.something. For that there should be some magic which updates your Example component state when window.something changes. Then the component gets updated smoothly.

I suggest second method and use a store system like Redux to implement that magic.

Joby Joseph
  • 2,177
  • 3
  • 15
  • 19