Uncaught TypeError: Cannot read property '$wire' of undefined

What seems to be the problem:
JavaScript error: Uncaught TypeError: Cannot read property '$wire' of undefined
when using @ this.upload() as documented in https://laravel-livewire.com/docs/2.x/file-uploads#js-api

Steps to Reproduce:
Made a minimal setup, no styles or scripts other than livewire (see code below).
The error appears in the browser console when the page loads.

Are you using the latest version of Livewire:
Yes, Laravel 8.13.0 and Livewire 2.3.1

Do you have any screenshots or code examples:

livewire-test:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Livewire minimal</title>
    @livewireStyles
</head>
<body>
    {{ $slot }}
    @livewireScripts
    @stack('scripts')
</body>
</html>

The route view:

<x-livewire-test>
    @livewire('file-upload')
</x-livewire-test>

The livewire file-upload component:

class FileUpload extends Component
{
    use WithFileUploads;
    public $photo;
    public function render()
    {
        return view('livewire.file-upload');
    }
}

The livewire.file-upload view:

<form wire:submit.prevent="save">
	<input type="file" wire:model="photo" accept="image/*">
	@if($photo)
	<img src="{{ $photo->temporaryUrl() }}">
	@endif
</form>

@push('scripts')
<script>
	let file = document.querySelector('input[type="file"]').files[0]

	// Upload a file:
	@this.upload('photo', file, (uploadedFilename) => {
		// Success callback.
	}, () => {
		// Error callback.
	}, (event) => {
		// Progress callback.
		// event.detail.progress contains a number between 1 and 100 as the upload progresses.
	})
</script>
@endpush

Don’t confuse the Upload API with the Progress API.
To make this work, only change the livewire.file-upload view.

Here is how one can use the Progress API without alpine.js

<form>
    <input type="file" wire:model="photo" accept="image/*">
    @if($photo)
    <img src="{{ $photo->temporaryUrl() }}">
    @endif
</form>

@push('scripts')
<script>
    let input = document.querySelector('input[type="file"]');
    input.addEventListener('livewire-upload-start', () => console.log('livewire-upload-start'));
    input.addEventListener('livewire-upload-finish', () => console.log('livewire-upload-finish'));
    input.addEventListener('livewire-upload-error', () => console.log('livewire-upload-error'));
    input.addEventListener('livewire-upload-progress', (event) => console.log(event.detail.progress));
</script>
@endpush

Here’s a working example of the upload API:

<div>
	<input type="file" accept="image/*">
	<button onclick="uploadFunction()">submit</button>
	@if($photo)
	<img src="{{ $photo->temporaryUrl() }}">
	@endif
</div>

@push('scripts')
<script>
	function uploadFunction() {
		console.log('upload');
		let file = document.querySelector('input[type="file"]').files[0];

		// Upload a file:
		@this.upload('photo', file, (uploadedFilename) => {
			console.log('uploaded: ' + uploadedFilename);
		}, () => {
			console.log('error');
		}, (event) => {
			console.log('progress', event.detail.progress)
		});
	}
</script>
@endpush