Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

275
Views
React.js: react on changes in external object

After reading official react.js documentation I understand how it should work in a good way, like

  1. I have list of items in initial component state
  2. adding new item through setState will update state and trigger update of UI

What should I do if I use external object as model like some global array which should be available for some not react.js parts of code OR could be modified with web sockets somewhere in future? Is calling ReactDOM.render after each action a good way? AFAIK it should work ok from performance point of view.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

You still use setState:

let React = require('React');
let externalThing = require('tools/vendor/whoever/external-lib');

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = this.getInitialState();
  }
  getInitialState() {
    // This assumes your external thing is written by someone who was
    // smart enough to not allow direct manipulation (because JS has
    // no way to monitor primitives for changes), and made sure
    // to offer API functions that allow for event handling etc.
    externalThing.registerChangeListener(() => this.updateBasedOnChanges(externalThing));
    return { data: externalThing.data }        
  }
  updateBasedOnChanges(externalThing) {
    // note that setState does NOT automatically trigger render(),
    // because React is smarter than that. It will only trigger
    // render() if it sees that this new 'data' is different
    // (either by being a different thing entirely, or having
    // different content)
    this.setState({
      data: externalThing.data
    });
  }
  render() {
    // ...
  }
}

If the external thing you're using is terribly written and you have to manipulate its data directly, your first step is to write an API for it so you don't directly manipulate that data.

let externalData = require('externaldata') // example: this is a shared array
let ExternalDataAPI = new ExternalDataAPI(externalData);
...

And then you make sure that API has all the update and event hooks:

class ExternalDataAPI {
  constructor(data) {
    this.data = data;
    this.listeners = [];
  }
  addListener(fn) {
    this.listeners.push(fn);
  }
  update(...) {
    // do something with data
    this.listeners.forEach(fn => fn());
  }
  ...
}

Alternatively, there are frameworks that already do this for you (flux, etc) but they also somewhat dictate how many more things "should be done" so that might be overkill for your need.

over 4 years ago · Santiago Trujillo Report

0

Since your question is about organizing your code in a manageable way, I would first of all suggest pairing ReactJS with a Flux-type framework, like Redux or Relay.

If you want to skip that for now, then you can organize your project using some react components at the top of the hierarchy for storing and retrieving data. For example, in such a component, in its componentWillMount method, you can start a setTimeout that periodically checks your global array and calls setState when appropriate. The render method should then contain child components that receive this state as props.

Below is an example. Obviously, the timers can be replaced by whichever method you use to subscribe to your data changes.

// your global object
var globalState = {name: "Sherlock Holmes"}

function onData(callback) {
  setInterval(function(){
    callback(globalState)
  }, 1500)
}

var Child = React.createClass({  
  render: function() {
    return <h1>Hello, {this.props.name}</h1>;
  }
});

var Root = React.createClass({
  getInitialState: function() { 
    return {} 
  },
  componentWillMount: function() {
  	var that = this;
    this.props.onData(function(data){
    	that.setState({external: data})
    })
  },
  render: function() {
    if (this.state.external)
    	return <Child name={this.state.external.name}/>
    else
    	return <div>loading...</div>;
  }
});


ReactDOM
.render(<Root onData={onData} />, document.getElementById('container'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!