Infinite Loop On ComponentWillMount ReactJS
I'm trying to use ReactJS on Salesforce but the queries are quite problematic
Take a look at this code, trying to make something cool to get all data but the while isn't stop, don't know why, please help me and feel free to ask me anything
componentWillMount(){
let queryMore = true
let offSet = 0
let contents = []
while(queryMore) {
makeDeferredProvider()
let contentObject = SObjectModel.deferredObject('Content')
let retrieveOptions = {
limit: 10,
where: {
Type__c: { eq: 'Image' }
}
}
offSet > 0 ? retrieveOptions.offset = offSet : ''
let contentPromise = contentObject.retrieve(retrieveOptions)
contentPromise.then( records => {
records.forEach( record => {
let item = {
'name': record.get('Name'),
'id': record.get('Id')
}
contents.push(item)
})
records.length = 10 ? offSet += 10 : queryMore = false
}, error => {
console.log(error)
})
}
this.setState({
contents: contents
})
}
Answer
Async React will make this easier in the future, but right now you need to not block rendering while your promise is resolving.
Here's a high-level solution:
- Stop using ComponentWillMount. It is being deprecated.
- Stop using the while loop. It won't work with your promise. Get it working first then worry about queryMore later. See below.
- Add a field in the component state called "loading" and default it to true.
- Have a conditional in your render method to load a spinner (or NULL, or something) when "loading" equals true.
- In ComponentDidMount*, call your request logic and set state WITHIN the function passed into the .then method after you retrieved all the contents. Make sure to set "loading" to false there.
- The conditional in render should then render the contents.
Consider using JSForce (https://jsforce.github.io/) to connect to your object. It already has autoFetch logic included that could replace your queryMore logic.
* Using ComponentDidMount should work but it's probably a bad idea because the component will call out to SF on each render. You should probably use a handler and only call when you don't have the data in state or if you want to refresh for some other reason.
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM