 This guy React Pro made a video talking about an interview question. I didn't watch the video, but somebody sent me this video and said, Hey, you should do this interview question too. There's this code sandbox link and it has a description. So let's get started. Let me run the timer. Welcome to the meta react JS interview. Your task is to build a transfer list component. Transfer list allows users to pass items from one list to another. UX has provided a mockup should consist of two lists with directional action buttons, click one or multiple items and move the item to the other list by clicking the action buttons. Okay, there's a PNG file here with a mockup. So I can see there's one less on the left. There's a presumably empty list on the right. And if I check number one here and then press this right arrow, I assume one will appear on the right. And I assume it'll be unchecked when it goes to the right. And then when I check it on the right and then press the left arrow, it'll go back to the left. Now either it can go on the top. It can preserve the order it was originally in or it could always put it at the end or something. That's a design decision that will affect what possible options we have. So that's interesting. There's also the case of if I have one two here and I have three four here and I check all of them and then press a button. What happens? Well, maybe just play around with it. And see this is supposed to be done with react. I'm not really react guys. So probably have to look up things. I've used react a little bit, but so let's start by just making the UI app data index. So I assume I need to do my stuff in app. So I think it the instruction said build a transfer list component that's so I got to make a separate function. So let's why didn't it? Okay, I should open this and that. Okay, is there a way to put this at the bottom? What it crashed? Oh, I don't know how to put it at the bottom. Well, wasting time. Whatever. Okay, so we would want function double list. We're going to call the component double list. And then they're just going to double lists. It's kind of pointless, but whatever. So we need we need three columns. So one column is going to be the left column. The middle column is going to have two buttons, which is I can't do that. You have to do a less than and button greater than this editor is weird. You hit enter and it doesn't enter. Okay, we got our buttons and then div. Now these are lists. So I'm going to use UL instead of the div the items are allies. So we have a list of all the items. That was in that data JS. So we have to load the data from data JS items from data JS. And if we just throw them in here, one, two, three, four. So I need one item per one li per item. So item is an li and we throw the item text in there. And we get a bunch of check. Well, not checkmarks, but bullet item things. Now they need checkmarks. So we're going to have a checkmark input type checkbox closed label. Now it is clickable and let's just make a little component for that, I guess. It has a label. Okay, now we need to do stuff when you click the right button, for example. So let's add a move to write function to write and what the move to write needs to do is look at everything that's checked. So how do we look at everything that's checked? Well, there's several options we could have. We could enumerate all the DOM nodes. So enumerate all the DOM nodes the right way. You have to use ref seems kind of dirty. Another way is every time you check an item, you add it to a set of checked items. And that would be a react state. That's another option. We could also, I guess query a forum. You could do a use ref on a forum. We would have to give unique IDs to unique names to everything. But if use ref use ref on each checkbox use ref on a forum or react state, I guess react state is probably going to be the most popular option most understandable by other people. But then you have to worry about state synchronization. I also realized I forgot key on the item. I need to have a key. There's some console log things. Each child and a list should have key. I have that. I guess that was old. Okay. Yeah. How are we going to do the checkbox state? And then how do we, I guess we can use the index. How do we identify each item? Right now we're getting items from this data jazz. We can use the index. We can use the label. I guess we're not told what is relevant in terms of the what's the uniqueness of the thing. It's not clear. I guess I could just use indices for now. And then we probably need to change it later. So we can call that the ID. And the ID is the index. Now each checkbox, I guess we'll just do a on change. On change is not the change. So let me just make sure this works. If I click ASDF. Okay. And kind of log the events, synthetic events. I can probably ask if it's checked or not by saying events, dots, target, checked. Is that going to work? True, false, true, false. That looks right. It reacts to keyboard events too. So event target checked is probably what we want. So we would have on checked, changed, on checked, changed. And we give it the ID and we give it the whether it's checked or not on check, changed ID and is checked. And we have to pass that function here. So now we can maintain a set, for example, a set of what all the things that are checked or it could be a map from the ID to is it checked or not, or a list of everything that's checked instead of a set. We'll do with a list or an array rather, because I don't know, checked IDs, set checked. Now I have to import you state, I guess import you state from react. Is that the import? Seems so. So checked IDs, push ID. Well, actually, we need to say if you're checked at it. Else checked IDs. Gotta remove it. Oh, you can't just push because we got to do Reacty thingies to do this stuff. Old checked IDs. Okay. Say new checked IDs is old checked IDs filter. This is the thing that stinks about React, isn't it? So we're removing all of the, we're removing the checked ID and then if you're checked, then we add it again. That should handle all the cases, I think. I'm regretting not using the ref solution, because the ref solution would handle all that for us. Anyway, set checked IDs, return new checked. And then we're going to log. Actually, when you click the button will log what's checked. So now this isn't working. Oh, no. Oh, because I'm not clicking the button to right. Okay. Now we have three of them checked and then we uncheck. Yeah, seems to be maintaining the IDs correctly. Okay. And then we need to move them to the right. So. To see whether things go on the left or on the right. There's a few approaches. We can have two lists, one for the left for the right. We could have a list of Booleans indicating left or right. I like the list of Booleans idea. We can also have a list of IDs of things that are on the right. Let's do the list of Booleans. Um, sites. Set sites. I do it.com. Gray corresponding to items. True equals right. False undefined is left. So here for these items. I want to show only the items that are on the left. So I need to say item index. If the, let's call it ID. If the item ID, if sides of ID is falsely. Then it goes on the left list. And then if it's truthy, it goes in the right list. All we got to do to move it to the right. Well, actually here. Yeah, we loop over all the checked IDs and say. We got to do this again. Set sides. Hold sides. New sides is a copy of the old sides. And we loop, loop through all the things we say. New sides. ID is true. True means on the right. Now if we go, what are these errors? Is this my phone? No clue. Point sides undefined. Oh, forgot to call return new sides. Do, do, bleep. Hey, it moved blue. That was not moving over. Why isn't it moving over? Because I do a filter and then a map. That's a problem. Because when I do this filter, it changes the index. What I'm using the index is ID. So I need to combine the filter and the map operations. I'll need to say that's then do that. This isn't the best code. We'll clean it up. Maybe I'll have to do something like that. And then copy paste. Where's the reference? Index. Oops. What? Index. ID. ID. Okay. Let's try again. Move it over. Move it over. Move it over. Move it over. It's all working. Now we got to move them back over to the other side. Move to left. Let me just copy paste the code, right? Easy. We'll clean it up later. Never. So set that to false. Mode to left. Oops. Move to left. I can move those over. And we can see when you check items and hit right, they're visibly unchecked, but we still have our state variable checked IDs, which thinks they're all checked. So when you move them back left, they all move. So our checked IDs is out of sync with this guy. Okay. It's making me regret using use state. So we could either continue using use state and do some bi-directional state sync or use refs. Like scan this approach and use refs. The reactive thing to do is this stupid use state. I guess I'll do the reactive way. Checked is checked. And we have to copy paste this. Checked is checked IDs includes ID. Reset the app state. Check one and two. Move it over. We didn't clear it. So they're still there, but now it's visibly, it visibly makes sense. Now the description did not say what happens when you click the button, whether it unchecked items or not. It didn't say. They didn't say. But we could fix that. We could do some code cleanup now. And then we can fix that issue. So move to side. If you say moved to side and pass in the side, we can just do that. And this can be moved to side. Left is false. And this would be moved to side. True. Message is real. Clearly that means a right parent was where it wasn't supposed to be. And then when you moved to side, anything that you moved, anything that was checked, we would clear from checked IDs, which I guess that's the same as just clearing checked IDs. You just say. Set checked IDs to empty. Right. And now when you move it, it clears it. There's some duplication here. We can make a, I mean, functionally it works. I don't know what else I should do here. Other than just refactoring code cleanup. Oh yeah, we need to make the UI. So the format of the code. Let's make the UI. So we need to give her the dots. The dots are because item style list style item none. Whoops. Like to mapping. I have to do it like this. I haven't done this stuff a long time. It's just gone. What? The style not work. No, it's just gone. Right. Refresh. Did you mean list style? Okay. Change the caps. Wonderful. No wonder people like tailing because it's broken. List style item. None is incorrect. What must it be? Type. None. Okay. It's list style type. Okay. That's gone. We have to add the border around the side. Maybe it can make a component for that. It's quite ugly. Order. One PX solid black. Throw something in there. Order radius. It's not quite black. It's more like what color should I pick? 555. 666 the magic number. And then I was to duplicate it up here. So maybe I should factor the code. I don't feel like factoring the code. I don't think that's important for the interview. But you know, you'll do that. And then we need to put them all side by side. I prefer using grid for this kind of thing. It's a div, style, display, grid, grid template areas is what I always go to. And it would be left, buttons, right, close the div. And then this needs a grid area of left buttons. Red everywhere. Oops. Why aren't they side by side? Why is there space? Why can't I see the browser anymore? Okay, that's still not right. Why is there space? See it's left buttons, right? No. Well, I'm doing something dumb. Grid template areas. Well, here I would just research the right way to do it. Side by side. Kind of cheat. Kind of just look at my website, how I did this. Blah, blah, blah, blah. Grid. Where's grid? Where's grid stuff? Header. Grid. Grid to template areas. Oh, they all go in the same double quotes. That's how it works. I thought it was a slash delineated. So it's like this. And then you want to center the buttons. Put them on separate lines probably. Make them thick. What, like 0.5 EMS? That's a bit aggressive. Not 15, 1. Is that about right? That's about right. Copy, paste. And then we got to make it on a separate line. So let's just throw in a BR. Then we have to center it. Oh, centering. Everybody loves centering. How do you center a div? I guess we could do a flex box, right? So then you don't need the BR. So display, flex. Whoops. Flex direction. Column, no rows. Flex direction. What is it? Flex something. I'm not a flex box guy. Flex, flex direction. Column. Flex direction column. There we go. Okay. And then space. Justify. Items. Center or something. I always fiddle around with flex to get the. Line items. Okay, that looks good. Line items. Center. And then hope. Isn't it justify items? Center. Just like content center. I don't remember the difference center. We need a small gap between the buttons. Gap between the buttons. You do that with a margin. How big is this gap? That was too much of a margin. Right. Because it gets split because it's flex box. The margins don't collapse. I mean, there's color tweaks you need to make. And these don't have the padding that they need. You know, just a bunch of small, style-y things. I'm not happy with this editor flow. Padding. 2M. Can add spacing between the buttons. I don't know. I think this interviews. The interview would say, okay, we get it. I think. I think they'd say, fine. Maybe improvements. Like if you have checked some items and then you move it, if I hit left here, maybe you should just leave them checked. Because maybe I just hit the wrong button and doesn't want to reset the position. You know, there's like user experience things that you might care about. I just don't have a good specification. About this task. And then there's things like it just word breaks. If it's too small, like I don't know what they want. Probably should set a max width. So it doesn't go too crazy. Maybe I would make the click region bigger. So it's easier to click the items. So now the click region is bigger. Oh yeah. So also you'll probably want to get the data out. Like whenever they make a change, either they'll be like a submit button or it'll like auto send to the server. There's no way our component does that right now. Also our component is hard coded to accept this items. So maybe we should accept items as a prop items is items. And we would have a callback. I guess whenever something moves around, I guess we would have a on changed sides is console.log. And there's definitely cleanup that can happen here. But whenever we could just do a use effects. So whenever sides changes, we call the callback with sides. This thing depends, yes. You need to depend on the callback in case the callback changes. So now, well, there's useless array updates. We can optimize that later, but undefined undefined undefined true. Because only the fourth item and then there should be a true at the beginning. True undefined undefined true. There's considerations like if they change the set of items, we already talked about how the, we don't have IDs for items. So if they change the items, what should the behavior be? Should always go to the left list. If they add new items, if they remove items. How do we detect that it was removed? It's under specified, but now I guess there's my solution. I don't like it. I think this checkbox state synchronization stuff. I don't like it. I think I would have been better with use ref on the forum. And then we can query selector all the checked things. I mean, that has its own complications, but I think that would have been cleaner than two way binding. Also, I probably, well, I should also make a component to avoid duplicating this guy and this guy or at least a helper function or something. Because that's a bunch of copy pasted code with the only difference being this. Whether it's sides or not sides. Similarly with these buttons, these left and right buttons. The styling is the same. Maybe I would make a CSS class for that. Or if we hate CSS classes, then I would make a component for it. And as I mentioned, there's opportunities for optimizations. Such as, if they just click the button, we shouldn't send a on change sides thingy. We could say if checked IDs is empty. Just return old sites. I don't do any change. So now if you click, I can't tell how to clear the console. And if you click the button, it doesn't do any redundant updates. Also, depending on how you want to use list, maybe we don't want a list of maybe we don't want a list of all the sides. Maybe you just want the updates wasn't specified what the outside needs outside code needs from the components. Like do you send incremental updates to the server or do you send the final state to the server unclear. There's trade offs to both approaches. But yeah, in a real interview, it wouldn't be a monologue. I would have somebody to talk to and they would be giving responses and telling me am I going not just am I going in the right direction, but also what I should focus on for the interview. Should I care about making these components? Does the interviewer want me to make these components to prove that I can make the components? I demonstrated once that I can make a helper component already. Do they want to see more of that? You know, when I asked the question of should I use use ref or use state interviewer could have told me oh, I want you to use you state or oh, I want you to use use ref. Or when I brought up the use ref solution, maybe interviewer wasn't familiar with what I had in mind. So they could ask for clarification. So a real interview would be a bit longer and also a bit shorter because there would be less of me kind of guessing at what the interviewer wants because I could just ask, but there would also be more just conversation. So that is my interview pause split. And I stopped the timer a bit late but whatever. My comments on the interview question. I think the interview question does leave some room for interpretation. For example, I chose one decision I chose was each item either has as a Boolean of left or right. But you could have done the to list solution and the to list solution has different consequences and different implementation considerations. I like that aspect of the question. I like that the question involved not just DOM HTML stuff but also some styling. However, the styling was kind of uninteresting or whatever. But overall that it seems very small of an interview question and it doesn't have enough open ended questions that I can see anyway. I guess that's good because they want you to actually code something. So I'm used to more design interviews where it's more of a conversation. And if you have a conversation you could talk about the trade off without actually writing the code because if you write the code it takes longer to do that. So if there's fewer options. That means you could just get to the code. So if the point is to evaluate code ability. Yeah, I guess it's a fine thing. I mean, if you just took this code and said this is representative of straggers coding. Well, it's not. I didn't do refactoring. But again, that goes back to I would ask the interviewer should I do refactoring, or do you get it, you know, do you trust my ability to refactor this code, or should I do it because you want to evaluate that. Also, in a more professional setting, I would include tests for the behavior and maybe documentation for what happens if if I move one over and then I move one back should it go to the end of the list at the beginning or where it was. That was unspecified. And if I check on the left and I click the left arrow, what should happen there, unspecified. I would have tests for those cases if those cases mattered. Wouldn't have dressed as a hobbit. True. I'm also missing accessibility stuff. I don't know if the interviewer cared about accessibility stuff. No idea. Probably should have brought that up there in it. I was thinking about it. I was thinking about it. But I didn't bring it up. That was my mistake. Yeah, that was just a quick question somebody asked and I thought I would make a video about it. Hope you learned something.