Reputation: 1766
Getting this error when trying to land on my login
page of my react app that uses a Facebook social auth:
Error: facebookLogin(...): Nothing was returned from render.
This usually means a return statement is missing.
Or, to render nothing, return null.
The problem seems to originate from:
ReactDOM.render(routing, document.getElementById('root'));
I'm not sure how to fix it, I don't get any errors in my terminal.
Here is code that stems from the problem: axios codefor Facebook login
import axios from 'axios';
const facebookLogin = (accesstoken) => {
console.log(accesstoken);
axios
.post('http://localhost:8000/auth/convert-token', {
token: accesstoken,
backend: 'facebook',
grant_type: 'convert_token',
client_id: 'SECRET_ID',
client_secret:
'SECRET',
})
.then((res) => {
localStorage.setItem('access_token', res.data.access_token);
localStorage.setItem('refresh_token', res.data.refresh_token);
});
};
export default facebookLogin;
my login.js
code which uses an export from the above axios,
import React, { useState } from 'react';
import axiosInstance from '../../axios/Login';
import { useHistory } from 'react-router-dom';
import FacebookLogin from 'react-facebook-login';
import FbLogin from '../../axios/facebookLogin';
//MaterialUI
import Avatar from '@material-ui/core/Avatar';
import Button from '@material-ui/core/Button';
import CssBaseline from '@material-ui/core/CssBaseline';
import TextField from '@material-ui/core/TextField';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Checkbox from '@material-ui/core/Checkbox';
import Link from '@material-ui/core/Link';
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';
import Container from '@material-ui/core/Container';
const useStyles = makeStyles((theme) => ({
paper: {
marginTop: theme.spacing(8),
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main,
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing(1),
},
submit: {
margin: theme.spacing(3, 0, 2),
},
}));
export default function SignIn() {
const history = useHistory();
const initialFormData = Object.freeze({
email: '',
password: '',
});
const [formData, updateFormData] = useState(initialFormData);
const handleChange = (e) => {
updateFormData({
...formData,
[e.target.name]: e.target.value.trim(),
});
};
const handleSubmit = (e) => {
e.preventDefault();
console.log(formData);
axiosInstance
.post(`auth/token/`, {
grant_type: 'password',
username: formData.email,
password: formData.password,
client_id: 'SECRET_ID',
client_secret:
'SECRET',
})
.then((res) => {
console.log(res);
localStorage.setItem('access_token', res.data.access_token);
localStorage.setItem('refresh_token', res.data.refresh_token);
});
};
const responseFacebook = async (response) => {
FacebookLogin(response.accessToken);
};
const classes = useStyles();
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}></Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form className={classes.form} noValidate>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
autoFocus
onChange={handleChange}
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
onChange={handleChange}
/>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
onClick={handleSubmit}
>
Sign In
</Button>
<FbLogin
appId="SECRET"
fields="name,email,picture"
callback={responseFacebook}
/>
<Grid container>
<Grid item xs>
<Link href="#" variant="body2">
Forgot password?
</Link>
</Grid>
<Grid item>
<Link href="#" variant="body2">
{"Don't have an account? Sign Up"}
</Link>
</Grid>
</Grid>
</form>
</div>
</Container>
);
}
my index.js
import React from 'react';
import ReactDOM from 'react-dom';
//import * as serviceWorker from './serviceWorker';
import './index.css';
import { Route, BrowserRouter as Router, Switch } from 'react-router-dom';
import App from './App';
import Header from './components/Header';
import Footer from './components/Footer';
import Register from './components/auth/Register';
import Login from './components/auth/Login';
import Logout from './components/auth/Logout';
import Bucket from './components/dashboard/bucket/BucketLayout';
const routing = (
<Router>
<React.StrictMode>
<Header />
<Switch>
<Route exact path="/" component={App} />
<Route path="/register" component={Register} />
<Route path="/login" component={Login} />
<Route path="/logout" component={Logout} />
<Route path="/dash/:slug" component={Bucket} />
</Switch>
<Footer />
</React.StrictMode>
</Router>
);
ReactDOM.render(routing, document.getElementById('root'));
Would like to know why I'm getting this error because I'm new to React and I have been following a guide. Thank you very much! If the error is not coming from the code that I shared, then I assume it's an error coming from my backend.
Upvotes: 0
Views: 906
Reputation: 326
If you want to use your
import FbLogin from '../../axios/facebookLogin';
and
<FbLogin
appId="SECRET"
fields="name,email,picture"
callback={responseFacebook}
/>
like this, you should modfiy your facebookLogin.js
Insert a return statement in your function cause you use it like a react component.
import axios from 'axios';
const facebookLogin = (accesstoken) => {
console.log(accesstoken);
axios
.post('http://localhost:3000', {
token: accesstoken,
backend: 'facebook',
grant_type: 'convert_token',
client_id: 'SECRET_ID',
client_secret:
'SECRET',
})
.then((res) => {
localStorage.setItem('access_token', res.data.access_token);
localStorage.setItem('refresh_token', res.data.refresh_token);
});
return (' return something ') //or
//return null
};
export default facebookLogin;
But in this case you can use the battery included from react-facebook-login library. (You also imported it)
import FacebookLogin from 'react-facebook-login';
you don't have to write your own react component just use it from the lib.
<FacebookLogin
appId="1088597931155576"
autoLoad={true}
fields="name,email,picture"
onClick={componentClicked}
callback={responseFacebook} />
You can also take a look at the documentation -> https://github.com/sakchaicm/fb-login
Upvotes: 1
Reputation: 21364
You are suing facebookLogin
as a react component, because you are importing it as
import FbLogin from '../../axios/facebookLogin';
and then use it as
<FbLogin
appId="SECRET"
fields="name,email,picture"
callback={responseFacebook}
/>
But like the error is saying, that function doesn't return anything react can interpret for rendering.
It's really not clear what your intention here was, but your function is simply not a react component and as such doesn't make sense to be used as such. It's also not clear what your intentions were with passing these props to FbLogin
, because they are not being interpreted in your function.
Update: I've had a look at the FB npm package you are importing. It seems like you meant to use that instead of your own axios code. So just replace the FbLogin
in the code above with FacebookLogin
and things might work as you expect.
Upvotes: 3