I use react and jQuery. here's a part of my code.
Before react component mounts, I perform ajax request to know if user is logged in.
It is supposed to set state when a response returns status code 200.
am I incorrectly using bind(this)
?
componentWillMount: function(){
$.ajax({
url: "/is_signed_in",
method: "GET",
dataType: "json"
}).success(function(response){
this.setState({ signedIn: response.signed_in, currentUser: $.parseJSON(response.current_user) });
}.bind(this));
},
componentDidMount: function(){
console.log(this.state.signedIn);
}
Edit 01
when I do console.log(this);
in success(function(response){...})
callback.
this
was the below.
R…s.c…s.Constructor {props: Object, context: Object, state: Object, refs: Object, _reactInternalInstance: ReactCompositeComponentWrapper}_reactInternalInstance: ReactCompositeComponentWrapper_context: Object_currentElement: ReactElement_instance: ReactClass.createClass.Constructor_isOwnerNecessary: false_isTopLevel: false_mountImage: null_mountIndex: 0_mountOrder: 2_pendingCallbacks: null_pendingElement: null_pendingForceUpdate: false_pendingReplaceState: false_pendingStateQueue: null_renderedComponent: ReactCompositeComponentWrapper_rootNodeID: ".0"_warnedAboutRefsInRender: false__proto__: ReactCompositeComponentWrappercontext: Object__proto__: Object__defineGetter__: __defineGetter__()__defineSetter__: __defineSetter__()__lookupGetter__: __lookupGetter__()__lookupSetter__: __lookupSetter__()constructor: Object()hasOwnProperty: hasOwnProperty()isPrototypeOf: isPrototypeOf()propertyIsEnumerable: propertyIsEnumerable()toLocaleString: toLocaleString()toString: toString()valueOf: valueOf()get __proto__: get __proto__()set __proto__: set __proto__()getDOMNode: ()__reactBoundArguments: null__reactBoundContext: ReactClass.createClass.Constructor__reactBoundMethod: ()arguments: (...)bind: (newThis )caller: (...)length: 0name: ""__proto__: ()[[TargetFunction]]: ()[[BoundThis]]: ReactClass.createClass.Constructor[[BoundArgs]]: Array[0]props: Objectrefs: Object__proto__: ObjectrenderButtonSet: ()setSignedIn: ()__reactBoundArguments: null__reactBoundContext: ReactClass.createClass.Constructor__reactBoundMethod: setSignedIn(response)arguments: (...)caller: (...)length: 1name: "setSignedIn"prototype: setSignedIn__proto__: ()<function scope>arguments: (...)bind: (newThis )arguments: (...)caller: (...)length: 1name: ""prototype: boundMethod.bind__proto__: ()<function scope>caller: (...)length: 1name: ""__proto__: ()[[TargetFunction]]: setSignedIn(response)[[BoundThis]]: ReactClass.createClass.Constructor[[BoundArgs]]: Array[0]state: ObjectcurrentUser: Objectcreated_at: "2015-07-24T18:30:38.772+09:00"email: "[email protected]"facebook_account_url: nullfirstName: "유찬"github_account_url: nullgoogleplus_account_url: nullid: 1lastName: "서"linkedin_account_url: nullsns_avatar: nulltwitter_account_url: nullupdated_at: "2015-08-14T02:14:21.091+09:00"__proto__: ObjectsignedIn: true__proto__: Object__proto__: ReactClassComponent
Solutions
My code above was antipattern.
Follow one of the methods suggested by Answer i adopted.
Plus, React documentation already provided very useful solution about my case: Load Initial Data via AJAX
Also, setState is asynchronous.
That's why I thought setState not working when I log it on console.
After all, i checked inside render and pass as props to child components.
Yes, it is deprecated in jQuery 1.8 onwards. You should use . done() and use . fail() to catch the errors.
AJAX success is a global event. Global events are triggered on the document to call any handlers who may be listening. The ajaxSuccess event is only called if the request is successful. It is essentially a type function that's called when a request proceeds.
success : A callback function that is executed if the request succeeds.it takes as an argument the returned data. It is also passed the text status of the response. dataType : The type of data expected from the server. The default is Intelligent Guess (xml, json, script, text, html).
jquery ajax calls are asynchronous by default. So success & error functions will be called when the ajax load is complete. But your return statement will be executed just after the ajax call is started.
I think you shouldn't use an Ajax call for setState in componentWillMount; do it in componentDidMount.
If you don't want to do the first render before you're having data AND those data are just for initialization perform your call outside and on success render your view with the fetched data =====>
<Myview data={initialDataFromTheCallSuccess} /> and then put it in getInitialState
Read this if you choose this path (cause as stated in the doc this is not an anti-pattern on certain conditions): https://facebook.github.io/react/tips/props-in-getInitialState-as-anti-pattern.html
hope it helps
Edit: There is two way to do it the first one you fetch outside your react class
$.ajax({...}).success(function(res) {
<MyView data={res} /> // render your function on success
});
and in MyView you getInitialState from props "data". Use this method only if you need to call your get once (read the anti-pattern stuff).
Other method is doing what you are doing but in componentDidMount. https://facebook.github.io/react/tips/initial-ajax.html
Hope it's clearer
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With