React Facebook Login popping up on page load - reactjs

I have this code in React:
import React from 'react';
import { FACEBOOK_ID } from '../../../config/credentials';
import FacebookLogin from 'react-facebook-login/dist/facebook-login-render-props';
const responseFacebook = response => {
console.log(response);
};
const FacebookLoginButton = () => (
<div>
<FacebookLogin
appId={FACEBOOK_ID}
autoLoad
callback={responseFacebook}
render={renderProps => (
<button onClick={e => {
console.trace();
}
}>Login via FB</button>
)}
/>
</div>
);
export default FacebookLoginButton;
This is just a simple react facebook login, now my problem is when I reload my local development site, The facebook authorization always popup on load or when I am currently logged in, it automatically logins the user and returns to the console the information from Facebook. is that the normal behavior of this library? I am new to react so any comments would really be appreciated.
Edit:
I've researched a few videos like this one: https://www.youtube.com/watch?v=ea9KyE78qKI&t=10s
It seems like his facebook component popups too when he visit it on his local site at around 12:48 mark but got blocked because Chrome doesn't allow automatic popups.

Make autoLoad as false.
<FacebookLogin
appId={FACEBOOK_ID}
autoLoad={false}
callback={responseFacebook}
render={renderProps => (
<button onClick={e => {
console.trace();
}
}>Login via FB</button>
)}
/>

Just remove the autoLoad option will work fine.
By mentioning autoLoad will take autoLoad = true by default.
autoLoad = false or remove autoload will do the same thing.
Hope this will clear more.
const FacebookLoginButton = () => (
<div>
<FacebookLogin
appId={FACEBOOK_ID}
callback={responseFacebook}
render={renderProps => (
<button onClick={e => {
console.trace();
}
}>Login via FB</button>
)}
/>
</div>
);

Related

Window is undefined in NextJS + Tauri

What I'm trying to do:
I was using the appWindow from Tauri to access the appWindow.minimize(), appWindow.toggleMaximize(), and appWindow.close() to create a custom title bar.
What the code looks like:
import { appWindow } from "#tauri-apps/api/window";
const CustomTitleBar = () => {
const hasLoaded = hasLoadedCSR(); // custom hook for checking if component has mounted using useEffect
if (typeof window === "undefined") return <></>; // 1st attempt to disable SSR for this component
if (!hasLoaded) return <></>; // 2nd attempt to disable SSR for this component
return (
<>
<div data-tauri-drag-region className="titlebar">
<button
className="titlebar-button"
id="titlebar-minimize"
onClick={() => {
console.log("Clicked");
appWindow.minimize();
}}
>
<img
src="https://api.iconify.design/mdi:window-minimize.svg"
alt="minimize"
/>
</button>
<button
className="titlebar-button"
id="titlebar-maximize"
onClick={() => appWindow.toggleMaximize()}
>
<img
src="https://api.iconify.design/mdi:window-maximize.svg"
alt="maximize"
/>
</button>
<button className="titlebar-button" id="titlebar-close">
<img
src="https://api.iconify.design/mdi:close.svg"
alt="close"
onClick={() => appWindow.close()}
/>
</button>
</div>
</>
);
};
export default CustomTitleBar;
I basically did 2 attempts to solve the problem because I definitely think this is caused by SSR as mentioned by FabianLars in a similar question.
To fix the problem, I basically created another component using the dynamic function to force CSR for CustomTitleBar.
import dynamic from "next/dynamic";
const DynamicCustomTitleBar = dynamic(() => import("./CustomTitleBar"), {
ssr: false,
});
export default DynamicCustomTitleBar;
How I got around this issue is as follows.
If and when I use any of the #tauri-apps/api exports I wrap them in a component that I then import using the dynamic import flow without ssr. This is mainly to keep my project organized because I just create sort of a wrapper for every function that I might want to use from tauri-apps/api.
So I would make the following folder structure:
const TauriApiWrapComponent = dynamic(() => import("./TauriApiWrapComponent"), {
ssr: false,
});

react-toastify popup showing 2 times

Website error visual on chrome
I create a react website. On this website, I create a social login icon using firebase-hooks. But when I click on the social login button the pop-up shows. But after closing that pop-up I use react toastify to show the error. But always It's showing twice. and can't fix this problem
const SocialLogin = () => {
const navigate = useNavigate();
const location = useLocation();
const from = location.state?.from?.pathname || "/";
const [signInWithFacebook, facebookUser, facebookLoading, facebookError] =
useSignInWithFacebook(auth);
facebookError && toast.error(facebookError.message);
const [token] = useToken(facebookUser);
token && navigate(from, { replace: true });
return (
<div>
<div className="or">
<div></div>
OR
<div></div>
</div>
<div className="social-logins">
<p>{facebookLoading && `Loadin Please Wait`}</p>
<div className="social-btn" onClick={() => signInWithFacebook()}>
<SiFacebook />
<span>Facebook</span>
</div>
</div>
<ToastContainer pauseOnHover />
</div>
);
};
toast message will be appeared on every re render , you need to call toast when you get error message from fb , you need to call toast inside of useEffect, something like this
React.useEffect(() => {
if (facebookError.message) {
toast.error(facebookError.message);
}
}, [facebookError.message])

How to override notification configuration for specific notification only?

I use react-toastify for notifications in my React app. In its configuration I've set a default autoClose setting. Is there a way that I can override this setting for specific notifications only? Please find my current code below.
I set react-toastify default configuration in the index page:
import { ToastContainer } from "react-toastify";
<ToastContainer
closeButton={false}
autoClose={6000}
/>
On other pages I for example have the code blow. It's there where I would like to set a custom configuration for autoClose for that specific message only.
Notify({
message: `A message`,
});
This uses a component called Notify:
const User = ({ message, closeToast }) => (
<div key={0} className="notification">
<span style={{ backgroundImage: `url('/icons/user.svg')` }}></span>
<label dangerouslySetInnerHTML={{ __html: message }}></label>
<button onClick={closeToast}>+</button>
</div>
);
const Notification = (props) => {
const { message, user } = props;
return (
<div>
toast(<User message={message} />, {
className: "white-background",
bodyClassName: "grow-font-size",
progressClassName: "fancy-progress-bar",
})
</div>
);
};
According to the documentation for react-toastify, you can pass the autoClose prop into the toast() emitter, as well as the ToastContainer
toast('My message', {autoClose: 5000});
https://fkhadra.github.io/react-toastify/introduction/

React Web App Routing Works on Desktop (incl. Mobile Dev View), but not on Mobile Browsers

I'm really stuck on a problem with a React web app I'm building. I'm using the array.map() method to dynamically create dropdowns, and I'm finding that everything works beautifully on desktop browsers (including in the mobile view of Chrome dev tools), but not on actual mobile browsers. I would really appreciate your thoughts!
Expected Behavior
I expect the dropdowns to populate, usually from an array of objects. Then, when the user clicks on one of the items in the dropdown menu, it will either trigger (1) a function or (2) a link to another part of the React App. Note that I'm using react-router-dom to handle routing.
Observed Behavior on Mobile Browsers
The dropdowns populate correctly, but they malfunction when I select from among the options (see Figure 1).
This behavior is observable when the dropdown selection triggers both a (react-router-dom Component) and calls a function. In the limited cases when the function is called correctly, the correct parameters are passed and the function does execute correctly.
Code Snippits
This is an example of the code I'm using to generate the list of links. It is a simple React functional component that serves as the header to all settings pages in my app, and the Component is part of a React MaterializeCSS library, which seems to be working fine.:
const SettingsHeader = () => {
let { url } = useRouteMatch();
const { userAccess, styleItem, headerStyle, updateHeader, theme } = useContext(SettingsContext);
const options = userAccess.length ? (
userAccess.sort().map(permission => {
// Returns an object with details needed to build the component via a Settings Context function.
let details = styleItem(permission);
return (
<Link
key={permission}
to={`${url}${details.link}`}
onClick={() => updateHeader(permission)}
>
<Icon className={theme.text}>{details.icon}</Icon>
<span className={theme.text}> {details.text}</span>
</Link>
);
})
) : (
<h4 className="grey-text">
<Icon>warning</Icon> You don't have permission to edit any settings.
</h4>
);
return (
<h4 className={theme.text}>
<i className="material-icons">{headerStyle.icon}</i> {headerStyle.text}
<Dropdown
options={{ ... }}
trigger={
<Button className={"right " + theme.themeColor} node="button">
Views
</Button>
}
>
{options}
<a href="#!">
<Icon className="grey-text">close</Icon>
<span className="grey-text"> Close</span>
</a>
</Dropdown>
</h4>
);
}
This is an example of the code I'm using to generate a list of theme options, each of which calls a function in a React Context Component I'm using in many places in the App:
const ThemeSettings = () => {
// Brings in Theme update function from SettingsContext
const { changeTheme, theme } = useContext(SettingsContext);
// Array of possible themes.
const themesList = ['Burnt Orange', 'Chrome', 'Deep Purple', 'Earth', 'Fresh Green', 'Green', 'Maroon', 'Navy', 'Pink', 'Red', 'Royal Blue', 'Teal']
const themeOptions = themesList.map(theme => {
let themeObject = getTheme(theme);
return (
<a href="#!" key={theme} onClick={(e) => changeTheme(e, theme) }>
<Icon className={themeObject.text}>style</Icon>
<span className={themeObject.text}> {theme}</span>
</a>
)
});
return (
<Dropdown
options={{ ... }}
trigger={
<Button className={"left " + theme.themeColor} node="button">
Themes
</Button>
}
>
{ themeOptions }
<a href="#!">
<Icon className="grey-text">close</Icon>
<span className="grey-text"> Close</span>
</a>
</Dropdown>
);
}
Thanks very much for giving this a look!
This is a known MaterializeCSS bug for devices running iOS-13.
I was only able to find one workaround available at time of writing, mentioned by Falk in this issue thread:
To fix it, I had to check out the #v1-dev branch of
https://github.com/Dogfalo/materialize, build it with grunt release
and use the materialize.js in /dist folder for my project.

React - Browser's Back button doesn't work

In the following component, if I click on any of the two buttons, the URL in the address-bar gets changed.
In the list view if you click on the button Details the page get rendered and shows that particular item and the URL in the address bar get changed too.
And in the user view if you click on the "Back to overview" button, the page renders back to the list view and the URL gets changed again.
import React, { useState, useEffect, Fragment } from 'react'
import axios from 'axios'
const UserList = ({ id, setID }) => {
const [resources, setResources] = useState([])
const fetchResource = async () => {
const response = await axios.get(
'https://api.randomuser.me'
)
setResources(response.data.results)
}
useEffect(() => {
fetchResource()
}, [])
const renderItem = (item, userId) => {
const setURL = (e) => {
window.history.pushState(null, null, '/' + e)
setID(item.login.uuid)
}
const clearURL = (e) => {
window.history.back()
setID(null)
}
return (
<Fragment key={item.login.uuid}>
{userId ? (
// User view
<div>
<img src={item.picture.large} />
<h2>
{item.name.first}
</h2>
<p>
{item.phone}
<br />
{item.email}
</p>
<button onClick={() => clearURL('/')}>
Back to overview
</button>
</div>
) : (
// List view
<li>
<img src={item.picture.large} />
<h2>
{item.name.first}
</h2>
<button onClick={() => setURL(item.login.uuid)}>
Details
</button>
</li>
)}
</Fragment>
)
}
const user = resources.find(user => user.login.uuid === id)
if (user) {
// User view
return <div>{renderItem(user, true)}</div>
} else {
// List view
return (
<>
<ul>
{resources.map(user => renderItem(user, false))}
</ul>
</>
)
}
}
export default UserList
Everything is working fine.
However, the problem with this solution is that on user view, I cannot use the browsers back button to go back to the list view page.
Is there any way I can change this without using React Route?
So what I believe is happening is you are over-writing the 'history' of the browser. The 'history' is pretty much just a stack of paths you've been and when you click the back button it just pops the current path off the stack. I think that when your using 'window.history.pushState(null, null, '/' + e)' its setting the history = to null so there is nothing to go back to. I would recommend using react-router and just pushing a path ie. router.push('/whatever'). There are a bunch of ways to interact with the history through react without using the native history object. If you want to use the native history object https://developer.mozilla.org/en-US/docs/Web/API/History_API
Edit - I apologize your not overwritting the history, but I do still believe that the error is coming from passing a 'null' value as the 'state' param for the pushState method

Resources