filmov
tv
Material UI Dialog with React Hooks
![preview_player](https://i.ytimg.com/vi/T2caeX_oHnA/maxresdefault.jpg)
Показать описание
Hello today we are talking about Material-UI Dialogs and React hooks.
As you can see from last time we have our task dialog here and there are a couple of things I didn't finish last time, like adding new tasks and editing tasks.
As you can see the add new task button opens a dialog but there is nothing defaulted for status or assignee.
Additionally when I try to save there are a few bugs because I just didn't implement saving on the new attributes I added last time.
Also this is zoomed in now so you can see it better without me having to edit it, this is the actual size of the app.
I browse the Material UI Dialog documentation and just wanted to show you the fullWidth prop which I use here. Not the full screen Dialog, the fullWidth prop here. As you can see you can only set the maxWidth to the specified sizes here so I am going to override that myself with a custom pixel value.
Then of course we've got some other props here like whether the dialog is open, the onClose callback, and so forth.
Setting the width of the Material-UI Dialog requires you to set the fullWidth prop and then set the maxWidth prop to one of the breakpoint values like sm, md, etc. If you want to use a custom pixel value, you have to override the class with your own max-width CSS. Here is where I wrap the Dialog with styled-components to create my own Dialog CSS override, where I set the max width to 780px. This is where Material-UI is pretty inconvenient, sometimes I'd rather just use styled-components rather than their makeStyles hook.
Next I scroll through my Dialog to show you the various Dialog components like DialogContent, DialogActions and DialogTitle. These are pretty self explanatory containers and I show you what elements those correspond to in the above video.
So for existing tasks, this is where I conditionally render the TaskDialog based on whether a taskId is selected.
Here is where I use a render prop in the Dialog to tell the Dialog to render this button above the Dialog, this will keep the open/close state management within the Dialog component itself, this just makes it easier to move the dialog around and just specify what you want to render to trigger the opening of the dialog. And here is the callback where I set the dialog open.
So I forget exactly how I set taskId on the task table parent so I search for about 5 minutes and realize that when I click on the row, I push the task ID onto the history as you can see here. Then using React Router useParams, I pull the taskID off the URL and that's how I know to show the dialog when I click on a task. This is also great because you can just load the application on the task URL and it will automatically open up the dialog.
So now I look at this scratch code I've written here and decide its time to refactor this to clean it up. What I'm going to do now is instead of declaring each attribute in the task dialog, I'm going to simply use one React hook for setting the whole data object. This has the benefit of being really easy to save the data in the dialog because we're only storing the local state in one variable, data, rather than a bunch of attributes separately like this.
I also declare defaultTaskData so I know what to set on the Dialog when there is no current task selected.
I fall into a trap of trying to create separate setters for each attribute but instead opt to just make a function setAttr which we can use to set any key / value on my data. I really like to implement my own form behavior here and not to rely on something like formik.
I then also create a getter even though I could have just accessed data, I like this approach better.
I realize that now I will always have data so checking falsey data is not good enough to know whether I am in edit or add mode. I write a quick solution here but I end up refactoring this to a separate variable later as this approach doesn't work when I set default keys in the data.
The final bug I fix is in my Redux selector, I just need to make sure that where I assign the assignee to a person from my people slice, I use the default assignee when there is none. This creates basically a mock person that will be shared among other tasks that don't have an assignee. I import that and use it in my TaskDialog where I have defined the default task data, this should really be imported from the taskSlice or somewhere else but it is fine here for now.
So now you can see the unassigned person is there in my table.
My task editor is getting closer to being completed. Next time we'll update the Toast component to show correct messages after we edit and add tasks.
Thank you for watching, please check the description for links to this project if you want to explore the code further. I'll see you next time.
Комментарии