So there was a lot of talking, a lot of stuff being done,
now it's really time to make this button work and let us add a goal here,
right
and for that we need to find out what the user entered and thereafter, of course listen to a tap on the
button and then add the entered goal to an array of goals which we have to manage somewhere, which we
then can output down there in this bottom view,
right,
that's what we need to do. Now in this course,
I will use functional components only with the React hooks feature which is relatively new,
so in case you don't know React hooks yet, definitely learn about them first, for example in my React Complete
Guide,
I thoroughly cover them but attached you also find some other resources that get you started
with React hooks because we'll need React hooks to for example get the user input.
We used the useState hook for that which we import from React, not from React Native but from React, it's
a core React feature
and then here in this functional component, in this app component, we can get the entered goal and also
get the set entered goal function to update the state with the help of useState and by default, we
have an initial state which is an empty string because the user hasn't entered anything at the beginning.
Now we can bind this to the text input,
that means when the user types a character, we want to update our state and save the entered text in the
state here which we can then access through entered goal and we'll pass the entered goal back into the
text input. That's this two-way binding, it's a so-called controlled component which you also know from React
for web with normal HTML input elements.
So here we can listen to onChangeText, a prop provided by text input which takes a function that will
execute for every keystroke.
Now we could provide an inline function here but we can also set up a separate function to have a bit
of a cleaner code and you can have a function in a function and we need to have it in here, so we can
use our state or set entered goal function here, by simply adding a new function here,
goal input handler could be a name, the name is up to you though. In that function, we'll get the entered
text automatically, that will be passed in by React or by React Native here and we can then call set
entered goal and pass the entered text as a value because the entered text here will already be a string
because we connect goal input handler to onChangeText by simply pointing at it here. Now that's important,
don't add parentheses down there because this would execute this function when this code gets parsed,
so when the UI gets rendered for the first time. You don't want to execute this immediately though, you
want to execute it on every keystroke and therefore, you just take the name of the function, you pass that name
of the function to onChangeText and that effectively tells React Native, hey that's the function I
should execute for every keystroke, so don't add parentheses here so that this can run on every keystroke.
Now instead of this function syntax, you by the way also can use a different syntax which is the one
I will use throughout the course, where you create a constant with that name here and then the value
of that constant after equals sign is simply a function using that arrow function syntax, so then this
here is your argument list and this is the function body. That's normal Javascript syntax, it is supported
by the Javascript code React Native is able to run and therefore this is the syntax I will use, you
connect it to onChangeText exactly in the same way as before. Okay, so now we have this function connected,
we update our state with whatever the user entered on every keystroke,
now we also have to pass that text back into the text input, so that it's displayed there correctly by
simply binding the value property to entered goal, so to our state which will change with every keystroke.
And with that, we're getting access to the user input because it will now always be stored in an entered
goal. Now when the user presses the button, we want to use that entered goal, so for that I'll add another
function here, add goal handler and that's just a naming convention I'm using for these functions here,
you can name them whatever you want, whatever you are used to from your React apps, in the end the function
name should simply describe what's about to happen and that here will handle a press on that button which
in the end will then add a goal. Here the function won't take any arguments but in the function body,
I want to add my entered goal to a list of goals and we have no list yet,
so for now what I do here is console log, which is supported in React Native, entered goal so that we
at least see that this was saved correctly and that this function is executed. For this to execute, we
need to connect it to the button though, there we can add the onPress prop and point at the add goal
handler, again without parentheses so that this doesn't execute immediately but only when a press happens.
And now let's save all of that and let's go back and let's maybe enter learn React Native and the good
thing is you can use your real keyboard here and press add and you should see here in your terminal this
log, you'll also see this by the way in your expo dev tools here in the browser tab. There,
If you click on one of the connected devices, the one where you just click the button in my case, the
Android device, then there at the bottom you'll also see Learn React Native.
And of course it also works on iOS, learn all about React Native, if we enter this here and click
add, then we also see that being logged here and also see that in the expo dev tools, if we click on the
iPhone at the very bottom, we see this log. Okay
so we're getting the user input, we're storing it, we're console logging it, of course we don't want to
console log it, we want to output it below our input here instead, we want of a list of our goals below
this input area. So for that, we need that second view here which should output our list of items.
So here between the opening and closing tags, I want to output all the elements we added, all the goals
we added. For that we first of all need to manage our goals and we can set up another state for that
which initially is an empty array, hence I pass an empty array as a value to useState
and there we have our course goals and a set course goals function.
Now these names are always up to you but they should describe what's in your state and how you can update
it.
So now here when we add a goal, I want to update my course goals to add the new goal and for that, I can call
set course goals and now set course goals to a new array where I take my old course goals and add a
new one.
Now this is the syntax you might not know, that's the so-called spread operator,
it's a Javascript feature which takes an existing array and course goals is an array,
it's our current state snapshot before the update and pulls out all the elements from that array and
then adds them here to a new array which is why I have the surrounding square brackets, without this surrounding
square brackets
this would not work but now we create a new array and we add all the elements of the old array and now
we can also add a new element.
So here, I add a comma to add an extra element
after all the elements I'm pulling out here and the element I add here is my entered goal of course.
So now we update our list of goals with the old list of goals,
initially an empty list but then this will grow over time because we then also add a new goal
when we press that button. Now a tiny side note, when working with set course goals, course goals here is
our previous state and the way React updates the state,
this should always be your most current state snapshot but it's not 100% guaranteed, to have that
100% guarantee, when you update your state based on the old state,
you can use the function form of this set function where you don't pass the value of your new
state here
but instead you pass it in a function, typically an anonymous function where you get your current state
or current goals, so your current state snapshot and then you return your updated value,
so here I return my updated array with that inline arrow function syntax where if you only have one
expression, you can omit the curly braces and the return statement and just enter the value you want
to return and it will be returned and
that's all normal Javascript here, nothing React Native specific.
So here, I then take my current goals and then add my entered goal. This syntax is a bit better, the other
syntax would have worked as well but this is guaranteed to always work because React Native will here
always go ahead and give you the guarantee, the latest state snapshot before it then applies your state
change here.
Now that's all nice, we'll now have a list, an array of goals managed here. How can we now output this though?