Reactjs - what is the workflow to force a refresh? - javascript

I'm just trying to create a react component wrapping the CodeMirror (4.1) editor.
I came across this problem for which there is a workround via forcing a refresh once the component has loaded, but I'm not quite sure of the workflow I need to achieve this when react is added into the picture.
The suggestion is that to overcome the error I would need to
"Call .refresh() after resizing the wrapping container."
My code is currently as follows in the Editor component:
function ($, React, CodeMirror) {
return React.createClass({
render: function () {
console.log("render-editarea");
return (
<textarea id="editarea">
-- Comment here
USE [All Data Items];
SELECT ID FROM [Test Event]
</textarea>
)
},
componentDidMount: function () {
var onExecute = this.props.onExecute;
var editorNode = document.getElementById("editarea");
console.log("componentDidUpdate-editarea:" + editorNode);
var editor = CodeMirror.fromTextArea(editorNode, {
lineNumbers: true,
matchBrackets: true,
indentUnit: 4,
mode: "text/x-mssql",
extraKeys: {"Ctrl-E": function(cm) {
console.log(editor.getValue());
onExecute(editor.getValue());
}}
});
},
and it is loaded via the Render function of the parent component
I have tried
hooking the window resize event (as shown in the React manual) in
the editor component.
forcing a refresh in the parent component's componentDidMount
function using $("#editarea").refresh();
but neither of these appeared to work
So I'd be grateful if someone could show me the right way to do it.
Many thx

Use the ref attribute to reference rendered nodes rather than IDs or DOM selectors:
function ($, React, CodeMirror) {
return React.createClass({
render: function () {
console.log("render-editarea");
return (
<textarea ref="editarea">
-- Comment here
USE [All Data Items];
SELECT ID FROM [Test Event]
</textarea>
)
},
componentDidMount: function () {
var onExecute = this.props.onExecute;
var editorNode = this.refs.editarea;
console.log("componentDidUpdate-editarea:" + editorNode);
var editor = CodeMirror.fromTextArea(editorNode, {
lineNumbers: true,
matchBrackets: true,
indentUnit: 4,
mode: "text/x-mssql",
extraKeys: {"Ctrl-E": function(cm) {
console.log(editor.getValue());
onExecute(editor.getValue());
}}
});
},

So this post helped me. The .refresh() was a function on CodeMirror which I hadn't fully understood. I used the method as suggested in that post in the parents componentDidLoad event.
componentDidMount: function () {
$('.CodeMirror').each(function(i, el){
el.CodeMirror.refresh();
});
},

Related

ReactJS window.addEventListener("hashchange") not working

I have a React component called Home. Within Home, I have a function "urlListener" in which I have added an event listener to alert whenever the URL is being changed.
var Home = React.createClass({
getInitialState: function () {
return {
openedFile: this.props.location.query.file || '',
apps: [],
showNav: this.props.location.query.file ? false : true,
layout: 'row',
cloneAppName: 'New Application',
appName: 'Application Name',
showSave: false
}
},
urlListener: function(){
window.addEventListener("hashchange", function(){
saveUnsaved();
});
},
saveUnsaved: function(){
}
The listener works fine and is being called whenever there is a change in the URL. However, the console says that the function I'm trying to call is not a function. I am new to React and any help on this would be appreciated.
Someone had commented the answer which seemed to work for me, but the comment was removed before I could accept the answer. The correct way of doing it is
{() => this.saveUnsaved();}
The arrow function apparently switches the context from "window" to "this"(the current component) internally. Without the arrow function, "this" would be referring to the "window" component.
Works perfectly for me.
// ES6:
componentDidMount() {
window.addEventListener('popstate', this.handleOnUrlChange, false)
}
componentWillUnmount() {
window.removeEventListener('popstate', this.handleOnUrlChange, false)
}
handleOnUrlChange = () => {
// your code
}

vue is not defined on the instance but referenced during render

I'm trying to build a simple app in vue and I'm getting an error. My onScroll function behaves as expected, but my sayHello function returns an error when I click my button component
Property or method "sayHello" is not defined on the instance but
referenced during render. Make sure to declare reactive data
properties in the data option. (found in component )
Vue.component('test-item', {
template: '<div><button v-on:click="sayHello()">Hello</button></div>'
});
var app = new Vue({
el: '#app',
data: {
header: {
brightness: 100
}
},
methods: {
sayHello: function() {
console.log('Hello');
},
onScroll: function () {
this.header.brightness = (100 - this.$el.scrollTop / 8);
}
}
});
I feel like the answer is really obvious but I've tried searching and haven't come up with anything. Any help would be appreciated.
Thanks.
But for a few specific circumstances (mainly props) each component is completely isolated from each other. Separate data, variables, functions, etc. This includes their methods.
Thus, test-item has no sayHello method.
You can get rid of the warning by using .mount('#app') after the Vue instance rather than the el attribute.
Check the snippet below;
var app = new Vue({
data: {
header: {
brightness: 100
}
},
methods: {
sayHello: function() {
console.log('Hello');
},
onScroll: function () {
this.header.brightness = (100 - this.$el.scrollTop / 8);
}
}
}).mount('#app');
Please note; the following might not be necessary but did it along the way trying to solve the same issue: Laravel Elixir Vue 2 project.

Handling Direct Update with navigation to native page in IBM Mobile first

I am developing a project, in which i need to call a native page in wlCommonInit()
function wlCommonInit(){
WL.NativePage.show(nativePageClassName, backFromNativePage, params);
}
I want my project to receive the direct update with persession mode. So to connect with the Mobile First Server, I have called WL.Client.connect()
function wlCommonInit(){
busyind = new WL.BusyIndicator;
busyind.show();
WL.Client.connect({onSuccess: connectSuccess, onFailure: connectFail});
WL.NativePage.show(nativePageClassName, backFromNativePage, params);
}
More over I want to handle the direct update so I have added the required code.
wl_directUpdateChallengeHandler.handleDirectUpdate = function(directUpdateData,
directUpdateContext) {
// custom WL.SimpleDialog for Direct Update
var customDialogTitle = 'Custom Title Text';
var customDialogMessage = 'Custom Message Text';
var customButtonText1 = 'Update Application';
var customButtonText2 = 'Not Now';
WL.SimpleDialog.show(customDialogTitle, customDialogMessage, [{
text: customButtonText1,
handler: function() {
directUpdateContext.start(directUpdateCustomListener);
}
}, {
text: customButtonText2,
handler: function() {
wl_directUpdateChallengeHandler.submitFailure();
}
}]);
};
var directUpdateCustomListener = {
onStart: function(totalSize) {},
onProgress: function(status, totalSize, completeSize) {},
onFinish: function(status) {
WL.SimpleDialog.show('New Update Available', 'Press reload button to update to new version', [{
text: WL.ClientMessages.reload,
handler: WL.Client.reloadApp
}]);
}
};
Here the problem is, the application is navigating to the native page
before it can go to the direct update handler function when the direct
update is available.
Is there any way to resolve it?
I think what you should do instead if use the API [WL.Client.checkForDirectUpdate.
This way you will have the ability to first check for direct update - handle it if there is an update and then execute the function for opening the native page.
The code that is running is async, so you can't control it if you're not following the above suggestion.

React component not rendered

I have a file called App.js which is my application's main component.
I placed a new component in the result returned by that file's render method:
return (
<div>
<AjaxReq />
//many other components
</div>
);
Where AjaxReq is the following method:
'use strict';
var AjaxReq = React.createClass({
loadDoc: function() {
$.ajax({
url: "someUrl",
context: document.body,
success: function(){
$(this).addClass("done");
}
});
},
render: function() {
return (<div>
<p onClick={this.loadDoc}>
Click this to make AJAX request.
</p>
</div>);
}
});
module.exports = AjaxReq;
Unfortunately, this component is not rendered at all in the page.
Are there any issues with my code?
I don't think that this snippet $(this).addClass("done"); does what you might intend to do.
In that context, this refers to the React Component (Virtual DOM), not the actual element in the DOM.
The only way to access a React Component instance outside of React is by storing the return value of ReactDOM.render.
Also by any chance,have you forgotten to import React (var React = require('react') ) into your AjaxReq module?
Like phpcoderx said, not importing React could be causing nothing to render. To add the CSS class like you are trying to do, you would want to do something more like the following (though I don't think this would affect the lack of initial rendering issue you are seeing).
'use strict';
var AjaxReq = React.createClass({
loadDoc: function() {
$.ajax({
url: "someUrl",
context: document.body,
success: function(){
this.setState({ isLoaded: true });
}
});
},
getInitialState: function() {
return { isLoaded: false };
},
render: function() {
var classname = this.state.isLoaded ? 'done' : '';
return (<div className={classname}>
<p onClick={this.loadDoc}>
Click this to make AJAX request.
</p>
</div>);
};
});
module.exports = AjaxReq;

React js and bootstrap modal from examples on github

I'm trying to set up an app with react and everything is going well except for my modal. I've used this code from the following link, untouched and I get errors. https://github.com/facebook/react/blob/master/examples/jquery-bootstrap/js/app.js
Try this fiddle http://jsbin.com/eGocaZa/1/edit?html,css,output
The callback functions don't seem to have access to "this". If you log "this" in the console, it logs the window object.
openModal: function() {
this.refs.modal.open();
},
I did pass in this and return a new function which seemed to work but that didn't seem right and not playing nice with jsfiddle. I got the modal firing locally but then I run into the same issue with the close function. Any help would be appreciated. Thanks!
var Example = React.createClass({
handleCancel: function() {
if (confirm('Are you sure you want to cancel?')) {
this.refs.modal.close();
}
},
render: function() {
var modal = null;
modal = (
<BootstrapModal
ref="modal"
confirm="OK"
cancel="Cancel"
onCancel={this.handleCancel}
onConfirm={this.closeModal}
title="Hello, Bootstrap!">
This is a React component powered by jQuery and Bootstrap!
</BootstrapModal>
);
return (
<div className="example">
{modal}
<BootstrapButton onClick={this.openModal(this)}>Open modal</BootstrapButton>
</div>
);
},
openModal: function(obj) {
return function(){obj.refs.modal.open();}
},
closeModal: function() {
this.refs.modal.close();
}
});
I found a few problems with your code:
You were loading the Bootstrap JS before jQuery but it needs to be loaded after.
You were using React 0.3.0, which had different scoping rules for component methods -- since React 0.4, methods are bound to the component automatically. You could have written openModal: React.autoBind(function() { this.refs.modal.open(); }) or onClick={this.openModal.bind(this)} in React 0.3 but upgrading to 0.4 removes the necessity to bind manually.
Your modal had the hide class which seemed to make it invisible; I removed it and now the modal seems to appear. I'm not sure at the moment why this behaves differently between your code and the example.
Here's my working example jsbin . The modal appears to have some strange CSS applied to it but I don't think it's React-related so I'll leave you here. Let me know if anything's unclear.
Of course I worked on this all night and then figure the answer out after I ask a question here but here's the solution.
The functions needed to be wrapped in the autoBind to access "this". Here are the functions affected...
close: React.autoBind(function() {console.log(this);
$(this.getDOMNode()).modal('hide');
}),
open: React.autoBind(function() {
$(this.getDOMNode()).modal('show');
}),
...
handleCancel: React.autoBind(function() {
if (this.props.onCancel) {
this.props.onCancel();
}
}),
handleConfirm:React.autoBind(function() {
if (this.props.onConfirm) {
this.props.onConfirm();
}
})
...
openModal: React.autoBind(function() {
this.refs.modal.open();
}),
closeModal: React.autoBind(function() {
this.refs.modal.close();
})

Categories

Resources