In my application, I have written a function under a functional component and it doesn't work. It says, function is not defined no-undef. But I have written same kind of code in my previous project. What am I doing wrong here? If I convert this to a class component, this works fine. Is it possible to write a code like this? Or do I have to change it to a class component?
import React from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import {bindActionCreators} from 'redux';
import { connect } from 'react-redux';
import { logoutUser, clearCurrentProfile } from '../../actions';
const Navbar = props => {
const { isAuthenticated, user } = props.auth;
onLogoutClick = e => {
e.preventDefault();
props.clearCurrentProfile();
props.logoutUser();
}
const authLinks = (
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<Link className="nav-link" to="/feed">
Post Feed
</Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/dashboard">
Dashboard
</Link>
</li>
<li className="nav-item">
<img
className="rounded-circle"
style={{ width: '25px' }}
src={user.avatar}
alt={user.name}
/>
<button
type="button"
className="link-button nav-link"
onClick={() => this.onLogoutClick().bind(this)}>
Logout
</button>
</li>
</ul>
);
const guestLinks = (
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<Link className="nav-link" to="/register">
Sign Up
</Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/login">
Login
</Link>
</li>
</ul>
);
return (
<nav className="navbar navbar-expand-sm navbar-dark bg-dark mb-4">
<div className="container">
<Link className="navbar-brand" to="/">
DevConnector
</Link>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#mobile-nav">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="mobile-nav">
<ul className="navbar-nav mr-auto">
<li className="nav-item">
<Link className="nav-link" to="/profiles">
Developers
</Link>
</li>
</ul>
{isAuthenticated ? authLinks : guestLinks}
</div>
</div>
</nav>
);
};
Navbar.propTypes = {
logoutUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired
}
const mapStateToProps = state => ({
auth: state.auth
});
const mapDispatchToProps = dispatch => ({
logoutUser: bindActionCreators(logoutUser, dispatch),
clearCurrentProfile: bindActionCreators(clearCurrentProfile, dispatch)
});
export default connect(mapStateToProps, mapDispatchToProps)(Navbar);
Define with const onLogoutClick
, and you do not need this
keyword when calling it.
bind
is also unnecessary when you are already using arrow function for lexical binding.
const Navbar = props => {
// ...
const onLogoutClick = e => { // use consts or let
e.preventDefault()
props.clearCurrentProfile()
props.logoutUser()
}
const authLinks = (
// ...
<button
type="button"
className="link-button nav-link"
onClick={onLogoutClick} // no need 'this' keyword
>
...rest of your stuffs
You got some syntax error: function declaration onLogoutClick
must be started with const
or let
and the stateless component is just a function, so you don't need this
when calling it.
import React from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import {bindActionCreators} from 'redux';
import { connect } from 'react-redux';
import { logoutUser, clearCurrentProfile } from '../../actions';
const Navbar = props => {
const { isAuthenticated, user } = props.auth;
const onLogoutClick = e => {
e.preventDefault();
props.clearCurrentProfile();
props.logoutUser();
}
const authLinks = (
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<Link className="nav-link" to="/feed">
Post Feed
</Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/dashboard">
Dashboard
</Link>
</li>
<li className="nav-item">
<img
className="rounded-circle"
style={{ width: '25px' }}
src={user.avatar}
alt={user.name}
/>
<button
type="button"
className="link-button nav-link"
onClick={onLogoutClick}>
Logout
</button>
</li>
</ul>
);
const guestLinks = (
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<Link className="nav-link" to="/register">
Sign Up
</Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/login">
Login
</Link>
</li>
</ul>
);
return (
<nav className="navbar navbar-expand-sm navbar-dark bg-dark mb-4">
<div className="container">
<Link className="navbar-brand" to="/">
DevConnector
</Link>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#mobile-nav">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="mobile-nav">
<ul className="navbar-nav mr-auto">
<li className="nav-item">
<Link className="nav-link" to="/profiles">
Developers
</Link>
</li>
</ul>
{isAuthenticated ? authLinks : guestLinks}
</div>
</div>
</nav>
);
};
Navbar.propTypes = {
logoutUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired
}
const mapStateToProps = state => ({
auth: state.auth
});
const mapDispatchToProps = dispatch => ({
logoutUser: bindActionCreators(logoutUser, dispatch),
clearCurrentProfile: bindActionCreators(clearCurrentProfile, dispatch)
});
export default connect(mapStateToProps, mapDispatchToProps)(Navbar);
this is not available when using functional component. It is working when using class component because this is available.
change this
onClick={() => this.onLogoutClick().bind(this)}>
to
onClick={onLogoutClick()}>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.