Why Do We Use an Underscore _ in Front of Functions or Variables in Flutter (Dart)?

If you’re just starting out with Flutter, you’ve probably come across code that looks like this:

ElevatedButton(
  onPressed: _isLoading ? null : _login,
  child: _isLoading
      ? const CircularProgressIndicator()
      : const Text('Login'),
)

And then the question pops up:
“Why do we write _login with an underscore instead of just login?”

Good question! In this article, we’ll break down what the underscore (_) means in Dart/Flutter and why developers prefer to use _login instead of login.

1. Dart Has a Rule About the Underscore _

In some languages (like Python or JavaScript), putting an underscore at the start of a variable or function name is mostly just a naming convention.

But in Dart, the underscore has actual technical meaning:

An underscore at the beginning of a name makes it private (accessible only within the same file/library).

For example:

void _login() {
  print("This is a private function");
}

Here, _login cannot be called from outside the file.

But if you write:

void login() {
  print("This is a public function");
}

Then login can be called from anywhere as long as the file is imported.

2. Why Do Flutter Developers Use _ So Often?

Most of the time in Flutter apps, functions or variables are only used within one widget or state.

Take the login button in a login screen, for example.
Do we really need the login function to be accessible from other files? Not really.

That’s why developers write it like this:

class _LoginPageState extends State<LoginPage> {
  bool _isLoading = false;

  void _login() {
    setState(() {
      _isLoading = true;
    });

    // login logic goes here
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: _isLoading ? null : _login,
      child: _isLoading
          ? const CircularProgressIndicator()
          : const Text('Login'),
    );
  }
}

Notice:

  • _isLoading → used only inside this class.

  • _login → only needed for this button’s action.

If these were public (login), other files could call them unnecessarily.
So the solution is → add the underscore (_login).

3. The Difference Between login and _login

Let’s make it crystal clear with an example.

File: auth.dart

void login() {
  print("This is a PUBLIC login function");
}

void _login() {
  print("This is a PRIVATE login function");
}

File: main.dart

import 'auth.dart';

void main() {
  login();   //  Works fine
  _login();  //  ERROR: _login is private and only accessible within 'auth.dart'
}

The difference is clear:

  • login() → public, can be called from anywhere.

  • _login() → private, restricted to the file where it’s defined.

4. When Should You Use _?

Use an underscore _ when:

  • The variable/function is only needed in one file.

  • You don’t want other files (or developers) to access it directly.

  • Examples: _login, _isLoading, _fetchData, _controller.

Use no underscore when:

  • The variable/function is intended to be accessed from outside the file.

  • Examples: loginUser, ApiService, UserModel.

So, why do Flutter developers often use _login instead of login?

  1. Underscore means private → only accessible inside the same file.

  2. It’s safer → prevents accidental usage from other files.

  3. It’s cleaner → makes your code clearer about what’s internal vs public.

In short, if a function is only used by a specific widget (like a login button), name it _login. But if it’s something multiple files should access, then just use login without the underscore.

Now you know exactly why _login matters in Flutter/Dart.
If you’re learning Flutter, get into the habit of distinguishing between private functions (with _) and public functions (without _). It’ll make your code cleaner, safer, and much easier to maintain. 


0 Comments:

Posting Komentar