Flutter Bloc Tutorial - Bloc or Cubit?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
flutter has a lot of state management options but today we're going to be talking about block one of my favorite choices for state management in flutter we'll also cover the differences between blocks and qubits how to incorporate blocks into your flutter widget tree and then we'll show some examples in a real life application that touch on everything we're covering now like i mentioned before block is a predictable state management library for flutter but you can also use it with angulardart or even just start it's an alternative to other state management solutions like provider riverpod redux inherited widget and inherited provider mobx binder and many more blocks help you keep business logic out of your widgets when building a flutter application they also allow you to easily test logic and widgets separately for example when my state is x my widget should be doing y blocks also allow you to record interaction with those blocks through a block observer finally and perhaps most importantly blocks provides scalable conventions for teams of any size in a growing code base defining a block is fairly straightforward you'll create a new class that extends block and you'll provide types for the events and states that your block should support you'll provide an initial state for your block often this is a loading state and you'll set up event listeners and handlers in the constructor our handler functions take in the event of that type as well as an emitter of the state that we're supporting once we're finished doing our business logic our block will emit a new state indicating that something has changed perhaps we've loaded our data or maybe we failed to load our data events are also fairly straightforward you'll use a class to define events generally you have a root class for your events in this case pet event and you can use equatable to help prevent duplicate events from triggering back to back when your block processes them your event should have properties that represent all the data they need to perform whatever the event is intended to do for example if you're loading a pet you'll want to pass in the uuid for that pet if you're adding a pet you might want to take in a instance of that pet object that you're wanting to save to the database defining block state is also fairly straightforward the state is what's emitted by the block and your views react to changes in the blocked state views can also react to state changes without changing the widget tree you might use a scaffold messenger to show a snack bar or maybe just show a dialogue additionally you can leverage equatable to avoid triggering duplicate emissions of the same state if nothing has changed since the last time it was emitted now that we've covered the basics of blocks let's talk about a simpler alternative the qubit qubits don't define events but they do still define states instead of adding an event to the block you just add a method on the qubit and call that method now you're probably wondering which one should you use bach has more boilerplate but a smaller api surface just dot add because of this blocks are way easier to mock in widget tests because there's less public members and blocks also allow you to capture the event flow of your application you can log this to sentry firebase etc it also assists in debugging equatable events help prevent duplicate events from triggering like on a double tap and since qubits don't use events you don't have that luxury finally block has an event sync and while that's out of the scope of this video if you really want granular control or the ability to transform your events on the fly you're only going to be able to do that with block not qubit however the main reason to choose a qubit honestly is that it's a lot simpler there's less boilerplate and it's generally easier to wrap your head around especially if you're starting out with the block library what's really nice is that they actually operate fairly similar so you can swap out your choice later if you realize that maybe qubit wasn't right for you or maybe block wasn't right for you let's take a look at how blocks work so we define events in this case we have a load pet event a delete pet event and an update pet event we can call petblock.add and pass an instance of that event to the block that block will do some logic maybe it has a service that it calls or a repo that it fetches data from and then finally that handler will emit state qubits are extremely similar the only difference is that we don't have those events so these are now methods so you would have something like petcubit.loadpet or petcubit.deletepet and these methods is where you would put that business logic that blocks might have such as calling a service or a repository to fetch data and then in these methods you would also still emit state so which to use uh it really depends on you your team and your use case if your team values traceability blocks have a clear advantage over qubits if your team is having a hard time mocking qubits for testing blocks also provide an advantage there but if your team is struggling to model event transitions or find it unwieldy you might want to start with qubits and if your use case is really simple you may just want to use qubits in general because it'll likely be a little easier so how do blocks and qubits come together well it's through block base both qubit and block extend block base and the block based class is what's expected when adding blocks or qubits to the widget tree this also provides the interface that the block widgets use like block builder block consumer and block listener we'll get into those more in just a moment but the nice thing is that this allows blocks and qubits to be used similarly in the widget tree when building your flutter application the block builder is a flutter widget for listening to block state changes and creating widgets based on that state state changes trigger a rerun of the builder function provided to the block builder and an optional block parameter can be provided although if you emit it it will look up a matching block from the widget tree in this example we have a block builder for pet block and pet state our builder function looks at three different states whether it's loading failed or loaded and then ultimately if there's a state that we don't support we're simply just returning an empty container while these if statements are empty this is where you would create new widgets and return those to conditionally build your widget tree based off of the block state our next widget is the block listener this is a flutter widget for listening to block state changes and executing code when those state changes again state changes trigger a rerun of the listener function an optional block parameter can be provided but a mission will look up a matching block from the widget tree you don't want to create widgets here but you might do something like set state maybe pop the navigator or show a snack bar with a scaffold messenger in our example here we have a block listener set up for the pet block and we listen to state changes if the state is deleted we go ahead and take the user back via navigator pop if the state is pet updated we show them a snack bar indicating that the pet has been updated our next widget is the block consumer this one's really straightforward it combines the block listener and the block builder together so you can have both a listener and a builder if you're serious about using block make sure to check out the api docs there's way more to these widgets than listed here and you can provide functions that help determine if the widget should be rebuilt or if the listener should trigger again this video is just covering the basics and will eventually be out of date but blocklibrary.dev should stay up to date as well as providing more information i've mentioned that several widgets will look up a matching block from the widget tree if you don't manually provide one this poses the question of how do you get blocks into the widget tree well block provider is here to help us with that the block provider is a dependency injection widget it allows us to add blocks to the widget tree and it allows other widgets to get that block and add events to it or call methods for it in the case of qubits now that we have a high level understanding of blocks let's look at some actual code one of the things i mentioned about blocks specifically is that you can actually record changes to blocks to do this you'll create a new class that extends a block observer and override the onchange method you'll call super on change to make sure the blocks still work but you may want to do things like print the block and information about the events that it's processing we can create an instance of that block observer and we will add that to our block overrides dot run zoned the details about block overrides is probably out of the scope for this video but the documentation should have everything you need and who knows i may make another video talking about that if we look further down we can actually see our app build method and if we search we can actually find an instance of our pet block that i've mentioned before we're using the block provider widget that i've mentioned to create a new instance of our pet block and we're passing an instance of the pet repo to the pet block since that's a dependency for it if you have a lot of blocks like i do you can use the multi-block provider widget to nest all of your blocks roughly at the same level instead of having to nest block provider inside of block provider inside of block provider now let's take a look at the pet block as i mentioned this class extends block and takes in a type for the event and state in our case pet event and pet state you see that we set up our initial state and we have our listeners provided in the constructor this block's actually really simple since the repo is doing most the heavy lifting in this case but we emit a loading state then we fetch our data and then we emit loaded or our success state let's look at how we can consume these blocks so the simplest example is going to use the pets block we haven't talked about this one yet there's a block for pets and a block for pet but we have a list of data and you can see here that in did change dependencies we're using block provider of to add a new event to that pet block in this case when our widget dependencies change we want to make sure we're loading the correct pet in our build method you can see that we're using a block builder with the pet's block and the pet's state our builder function has conditionals for if the state is pets failed or the state is pet's initial or pets loading gonna take a second to clean this up really quick as this is a really good spot to show a circular progress indicator now we can take a look at the loaded state and you can see here in this conditional that we are getting state.pets and setting that equal to entries and then if entries is empty we let them know hey you don't have any pets yet let's add one but if that's not the case we use a list view builder and we pass in our state to that list view let's take a look at one more file we'll look at our pet.dart which is a view specifically for details about one pet this is the view that uses the pet block that we talked about so you can see here for example we're using blockprovider.of to get the pet block and if it's existing then we add an update pet event if it's not existing we add an ad pet event and these events will trigger any mounted block builder or block listener or block consumer i hope this video taught you something new about the block library and perhaps whether you should use blocks or qubits in your next flutter project if you learned something new i would really appreciate it if you liked the video and if you want to continue learning new things subscribe to the channel and click the bell to make sure that you get notifications of any new videos that i put out thank you so much have a great day
Info
Channel: Brad Cypert
Views: 7,542
Rating: undefined out of 5
Keywords:
Id: sAz_8pRIf5E
Channel Id: undefined
Length: 12min 11sec (731 seconds)
Published: Mon Sep 05 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.