How to get state from one react component to another? - reactjs

I'm new in ReactJS, that's why i'm here.
I created a component 'Login' and have variable 'isAuthenticated' in this.state.
After user login I change value of this variable to true and my app redirect user to home page.
In main page I must to check 'isAuthenticated' value and rerender component depends on it.
But it's not working. I got error: "Unable to get property 'setState' of undefined or null reference".
Please help me how to fix it all.

If you are not using something like Redux for your state management I suggest you use the localStorage of the browser to store that value for isAuthenitcated. Something like
localStorage.setItem('isAuthenticated', true); - on login
then in the other component you can use:
localStorage.getItem('isAuthenticated'); - to figure out what you want to show
remember to set isAuthenticated to false on logout as well!
localStorage.setItem('isAuthenticated', false); - on logout

I hope you will be having a login function like below
function login(){
doLogin().then(function(data){
this.setState({isAuthentcated: true});
});
}
Bind the login function to the component using ES6 Arrow function like this
login = () => {
doLogin().then((data) => {
this.setState({isAuthentcated: true});
});
}

Related

How to listen to navigate event?

Problem: I would like to use callback functions based on changes in href when user navigates within the same page.
For example, i would like to use a callback when a user navigates out of the component (changing href from localhost:3000/user to localhost:3000/about)
I've tried
popstate (which works when using forward/backward)
unload(works when i refresh)
pagehide/pageshow did not seem to respond at all.
visibilitychange fired whenever i moved out of the tab, but it was not what I was looking for.
You can use the useEffect cleanup function to trigger logic when the component unmounts.
useEffect(() => {
effect
return () => {
cleanup
}
}, [input])

React hook cleanup when refreshing the page

I have an app built in React using hooks that when closed needs to notify the server. I tried doing it using the following approach:
function onUnload() {
if (roomID !== "")
endGame(roomID, dispatch);
}
useEffect(() => {
return onUnload;
},[])
Here, endGame is a function that performs a HTTP request to the backend. But when refreshing the page to emulate a user closing the app, the request never reaches the server, meaning that the cleanup function doesn't get executed. Any ideas on what is wrong?
Thanks in advance
Refreshing the page is not same as component unmount. When you refresh the page, the React state is reset as React solely works on the current client session and refresh is equivalent to resetting it. What you are lloking for might be the onunload event. Try this:
window.onbeforeunload = function(e) {
return onUnload();
};

Where to put socket.io code in a component?

I want to connect to the coincap.io public socket.io API. I have everything set up but don't know where in my component to put the socket.io code. Does it go in the constructor or componentWillMount or where? It's socket.io so it obviously always needs to be open so where in a component would that go? Here is the code I need to inject somewhere into my component:
this.socket = io.connect('http://socket.coincap.io');
this.socket.on('connect', function(tradeMsg) {
console.log("It worked");
});
Does it go in the constructor or componentWillMount?
Check these answers for details about this:
Can I call APIs in componentWillMount in React?
Why do the React docs recommend doing AJAX in componentDidMount, not componentWillMount?
Where in my component to put the socket.io code?
Use componentDidMount lifecycle method for, it will triggered only once after the component has been mounted successfully, we should write all kind of network calls inside this.
As per DOC:
componentDidMount() is invoked immediately after a component is
mounted. Initialization that requires DOM nodes should go here. If you
need to load data from a remote endpoint, this is a good place to
instantiate the network request. Setting state in this method will
trigger a re-rendering.
Write it like this:
componentDidMount(){
this.socket = io.connect('http://socket.coincap.io');
this.socket.on('connect', function(tradeMsg) {
console.log("It worked");
});
}
You can add socket code into 'componentDidMount`. refer link
componentDidMount(){
this.socket = io.connect('http://socket.coincap.io');
this.socket.on('connect', function(tradeMsg) {
console.log("It worked");
});
}

Login ajax request Flux React?

How can I do
after login form submit (React Component)
using flux structure
ajax request that provides response ?
Can you provide some example ?
Basically you need to make an Ajax request, and then create success/error handlers. Inside those handlers, you will create actions to inform your stores of the result. It's probably a good idea to have an AppStore or SessionStore or something that will hold the data related to the current user and the auth token. Your controller-views can listen to that store and render their children when the current user becomes authenticated.
Here's how i made:
When my component bootstraps, I fire an INIT action to the Store which initially gets the datas i need. Here's the simplified data flow
After login my Library component is rendered so i need to initialize the data (books, users etc..)
Library:
componentDidMount: function() {
Store.addChangeListener(this._onChange);
Actions.initialize();
},
As you can see, when my component did mount, i fired a new action, and my store will handle this action.
Store:
switch(action.actionType) {
case Constants.INIT:
_init().done(function() {
Store.emitChange();
});
break;
I'm calling the private function _init() which will return a promise object. When the promise is Fulfilled the Store is ready to emit it's change event.
In _init I'm simulating some async data loads, thats why i made the promise, here it is:
function _init() {
var loadBooksDeferred = new jQuery.Deferred(),
loadUsersDeferred = new jQuery.Deferred(),
loadCategoriesDeferred = new jQuery.Deferred(),
stateReadyDfd = new jQuery.Deferred();
_loadBooks(loadBooksDeferred);
_loadUsers(loadUsersDeferred);
_loadCategories(loadCategoriesDeferred);
jQuery
.when(loadBooksDeferred, loadUsersDeferred, loadCategoriesDeferred)
.then(stateReadyDfd.resolve, stateReadyDfd.reject);
return stateReadyDfd;
}

In marionette view, redirect to another route when login success, given appRouter is not available in view function

I am using browserify to test water Marionette. I succeed to this point:
// Here is the singup function in LoginView which extends from Marionette.Layout.View
signin: function (e) {
e.preventDefault();
var email = $('#input-email').val();
var password = $('#input-password').val();
var userAuth = new UserAuthenticateModel({
email: email,
password: password
});
if(userAuth.isValid()) {
// signin
userAuth.save(null, {
success: function (model, resp, options) {
if(resp.code === 200) {
alert('login is good');
// I need to redirect to 'localhost:3333/app' route
// how should I do it? given appRouter, event/trigger is not available.
window.location.href = 'http://www.yahoo.com'; // It looks not a good solution
return;
}
if(resp.code === 406) {
// password doesn't match
alert('code 406');
}
},
error: function () {
alert('login http request is not successful');
}
});
} else {
// show error message
}
}
My question is, when login success, how should I redirect to another route? Given I am using Browserify to load module, there is no myAppRouter object available in global scope.
I guess there are 2 options, but I don't know how to implement them.
1) call myAppRouter (extends from Backbone.Marionette.AppRouter), but it is not available in view module, what shall I do? require it and new one? then it will be in a circular dependency.
2) use some kind event/trigger to send a route change msg to myAppRouter, but still I don't know how to do it.
3) other best practice to handle route change in view function when use login success, which I also don't know about. I am using browserify, please also take this into consideration.
Can somebody help me by provide some breif description and sample code? I prefer not in coffee script, since I can't understand it yet.
Thank you!
Looks like this is pretty close to your other question I just answered :). I'm not super familiar with browserify but can you take a look at my solution and see if that works for you as far as the listening to the App.vent message that gets triggered from the view/controller? If not let me know and I can dig a little more into browserify to see if I can figure out a better solution for you.

Resources