简体   繁体   中英

Writing a function inside a functional component in react

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM