1 00:00:00,470 --> 00:00:03,788 In React you typically don't target elements directly or 2 00:00:03,788 --> 00:00:08,490 modify them like you would when working with JavaScript and the DOM. 3 00:00:08,490 --> 00:00:12,361 For example, JavaScript provides selector methods, 4 00:00:12,361 --> 00:00:16,482 like get element by ID, that return an element in the DOM, 5 00:00:16,482 --> 00:00:21,720 which you can then manipulate, get, and set its text contents and more. 6 00:00:23,440 --> 00:00:27,585 To modify what a React component or element displays on the screen, 7 00:00:27,585 --> 00:00:29,340 you can use state and props. 8 00:00:30,440 --> 00:00:34,580 You trigger a state change and re-render the component with new props. 9 00:00:35,630 --> 00:00:39,923 If it's a component with local state or a controlled component, 10 00:00:39,923 --> 00:00:43,364 you will re-render it with every update and state. 11 00:00:43,364 --> 00:00:46,388 There may be times when you need to target and 12 00:00:46,388 --> 00:00:50,080 modify an element outside of that typical data flow. 13 00:00:51,280 --> 00:00:54,430 So React provides an escape hatch with refs. 14 00:00:54,430 --> 00:00:57,453 Refs let you access and interact with DOM nodes or 15 00:00:57,453 --> 00:01:01,270 React elements created in the return statement. 16 00:01:01,270 --> 00:01:06,260 They make it possible to let you do the more traditional DOM manipulation, and 17 00:01:06,260 --> 00:01:10,729 they're commonly used to access form elements and get their values. 18 00:01:10,729 --> 00:01:14,244 Earlier you learned how to update the value of an input 19 00:01:14,244 --> 00:01:17,683 field using state by creating a controlled component or 20 00:01:17,683 --> 00:01:20,900 a component with internally controlled state. 21 00:01:22,680 --> 00:01:24,474 We created a value state, 22 00:01:24,474 --> 00:01:29,130 then we wired the input fields to the function using the onChange event. 23 00:01:30,990 --> 00:01:34,770 For only one input field, writing this code is not a big deal. 24 00:01:36,570 --> 00:01:41,157 And this is still the recommended React way to control form elements, 25 00:01:41,157 --> 00:01:45,043 especially if you need to validate user input in real time or 26 00:01:45,043 --> 00:01:48,560 filter results with every keystroke, for example. 27 00:01:49,700 --> 00:01:54,627 However, if you're building a form that doesn't require internal state, 28 00:01:54,627 --> 00:01:59,877 you can use the ref attribute instead of calling on change for every state update. 29 00:01:59,877 --> 00:02:03,710 Let's create a ref that will access the player text field. 30 00:02:04,730 --> 00:02:07,756 You create a ref using the useRef hook, and 31 00:02:07,756 --> 00:02:12,480 then you attach the ref to the React element via the ref attribute. 32 00:02:13,520 --> 00:02:18,471 In the AddPlayerForm function I'll import useRef and 33 00:02:18,471 --> 00:02:24,720 create a ref name playerInput with const player input equals useRef. 34 00:02:26,660 --> 00:02:31,090 You can pass useRef an initial value as an argument. 35 00:02:31,090 --> 00:02:34,448 Since playerInput will reference the input element, 36 00:02:34,448 --> 00:02:36,500 we won't pass an initial value. 37 00:02:38,070 --> 00:02:43,130 Then attach this ref to the text input in the return statement by giving 38 00:02:43,130 --> 00:02:49,241 the input a ref attribute and passing it, the playerInput ref, with player input. 39 00:02:49,241 --> 00:02:54,660 This puts a reference to the input on the AddPlayerForm function. 40 00:02:54,660 --> 00:02:57,344 When the input is rendered onto the page, 41 00:02:57,344 --> 00:03:02,380 it returns the reference which you can access with playerInput. 42 00:03:02,380 --> 00:03:04,915 If I console.log playerInput, 43 00:03:04,915 --> 00:03:09,900 it returns an object with current pointing to the input element. 44 00:03:11,160 --> 00:03:14,940 It even selects and highlights the input in the browser. 45 00:03:14,940 --> 00:03:18,890 Great, the ref is now referencing the input element, and 46 00:03:18,890 --> 00:03:21,960 we can access it using its current property. 47 00:03:23,540 --> 00:03:28,238 In the handle submit function, instead of passing the value state to 48 00:03:28,238 --> 00:03:32,780 the addPlayer callback, I'll pass it the ref with playerInput. 49 00:03:34,750 --> 00:03:42,650 If the ref is a form element, you get the value of the ref with .current.value. 50 00:03:42,650 --> 00:03:47,486 Now we can delete the useState hook because we're no longer using the value 51 00:03:47,486 --> 00:03:48,540 state. 52 00:03:48,540 --> 00:03:53,522 That means we can also delete the useState import as well as the setValue 53 00:03:53,522 --> 00:03:57,012 function inside handle Submit, and the value and 54 00:03:57,012 --> 00:04:00,270 on change attributes from the input element. 55 00:04:02,130 --> 00:04:06,731 Let's test this in the browser to make sure that our add player functionality 56 00:04:06,731 --> 00:04:07,593 still works. 57 00:04:07,593 --> 00:04:12,045 Type a name into the text field, submit it, and it works. 58 00:04:12,045 --> 00:04:17,010 Now the form no longer resets the text field after submitting a name, 59 00:04:17,010 --> 00:04:18,474 this is a quick fix. 60 00:04:18,474 --> 00:04:22,282 One way we can reset the form is by writing 61 00:04:22,282 --> 00:04:28,335 event.currentTarget.reset in the handleSubmit function. 62 00:04:30,735 --> 00:04:35,840 I'll submit another player, and the input once again resets on submit. 63 00:04:35,840 --> 00:04:39,741 Good, as you can see, refs can provide an easier and 64 00:04:39,741 --> 00:04:43,030 quicker way to get values of an input field. 65 00:04:44,360 --> 00:04:45,620 When building forms, 66 00:04:45,620 --> 00:04:51,240 when should you use a controlled component instead of creating refs, and vice versa? 67 00:04:51,240 --> 00:04:54,715 Well controlled components have internal state and 68 00:04:54,715 --> 00:04:57,347 require functions to update state. 69 00:04:57,347 --> 00:05:01,430 They make it easier to modify or validate users input or 70 00:05:01,430 --> 00:05:05,796 even filter results based on the input, all in real time. 71 00:05:05,796 --> 00:05:09,929 Control components with state render on each keystroke, 72 00:05:09,929 --> 00:05:14,020 whereas in refs render is only called once. 73 00:05:14,020 --> 00:05:18,249 Whenever you're building a form that requires few inputs and 74 00:05:18,249 --> 00:05:23,614 you don't need to keep track of every keystroke, you have the option to create 75 00:05:23,614 --> 00:05:29,460 an uncontrolled component and use refs to get form values from the DOM. 76 00:05:29,460 --> 00:05:33,050 Let me show you another use for the useRef hook. 77 00:05:33,050 --> 00:05:37,540 In our App component, we created the state nextPlayerId to keep 78 00:05:37,540 --> 00:05:42,250 track of the player ID for when the new player is added. 79 00:05:42,250 --> 00:05:47,180 We actually should have used the useRef hook instead of the useState hook. 80 00:05:47,180 --> 00:05:51,687 You should use useState hook when you want to update data and 81 00:05:51,687 --> 00:05:53,500 cause the UI to update. 82 00:05:54,680 --> 00:05:59,762 In our case, nextPlayerId isn't being displayed to the UI so 83 00:05:59,762 --> 00:06:05,454 we don't want to cause a re-render when the nextPlayerId updates. 84 00:06:05,454 --> 00:06:08,340 And that's where the useRef hook comes in. 85 00:06:08,340 --> 00:06:13,256 If you need to store some data in React but don't want the component to re-render 86 00:06:13,256 --> 00:06:16,960 when the data updates, then you should use the useRef hook. 87 00:06:18,300 --> 00:06:22,463 I'll import the useRef hook at the top of the file and 88 00:06:22,463 --> 00:06:27,760 change nextPlayerId from state to a ref by typing const nextPlayerId 89 00:06:27,760 --> 00:06:32,790 equals useRef, and we'll keep the initial value the same. 90 00:06:33,920 --> 00:06:38,421 In handleAddPlayer function, let's delete the setNextPlayerId, 91 00:06:38,421 --> 00:06:42,010 since we don't have this function anymore. 92 00:06:42,010 --> 00:06:45,828 And change nextPlayerId, to 93 00:06:45,828 --> 00:06:50,748 nextPlayerId.current since we're using the useRef hook now. 94 00:06:50,748 --> 00:06:55,894 We can increment the nextPlayerId by adding nextPlayerId.current 95 00:06:55,894 --> 00:07:00,495 plus equals 1 under setPlayers, or 96 00:07:00,495 --> 00:07:05,660 we can add the increment operator here, either works. 97 00:07:07,000 --> 00:07:10,954 Alright, let's save our changes and have a look at the browser. 98 00:07:10,954 --> 00:07:15,871 In React dev tools you can see nextPlayerId is now a ref. 99 00:07:15,871 --> 00:07:20,361 When we add a new player the new player gets added to the state and 100 00:07:20,361 --> 00:07:23,430 nextPlayerId increments by one, great.