Creating a list of dynamic textfields with action parameters

Here is the end goal, a list of textfields to which you can add and remove items. This is in the context of a workout app where a user can start a workout, add an exercise and add sets (they need to be able to modify weight and reps for each new set).

The idea is to store the "currentWorkout" at the AppState level. When the page loads, the "currentWorkout" data is distributed to our widgets which will use the data as initial values to display. Whenever a user updates a textfield, we update the data at the AppState level and refresh all the widgets on our page to re-display information.

To achieve this, you will need to create 3 data types and 2 components.

Data Types

exerciseSet:

exercise (which contains a list of our first data type, exerciseSet):

workout (which contains a list of our previous data type, exercise):

We will also create an APP STATE VARIABLE of type "workout". This will hold our workout data.

Now we will create 2 components. 1 to hold an "exerciseSet" and one to hold an "exercise"

exerciseSet:

To display the initial set information for this particular set, we pass "currentExerciseSet" of data type "exerciseSet". This parameter will be used to set the initial values for the textfields.

We have created a local component state variable named "exerciseSet" which is of data type "exerciseSet". Whenever a textfield changes, we create a new "exerciseSet" and store it there.

We also pass an action for when we update a textField (to ultimately update the appState, rebuild the page and re-pass down all values) This action will be passed from the "exercise" component and returns the following action parameter:

So whenever the textfield changes, we update the local component state variable named "exerciseSet". This now holds the new values for the reps and weight, and then we execute the action passed as a parameter (and we set the "action parameter" as the newly updated exerciseSet value). This will allow us to use the new values when defining this action at the exercise level:

Now we will go one level up and create an "exercise" component which will be a listview of our exerciseSet component. This exercise component is passed down a parameter named "exercise" of data type exercise (from the component above). This exercise data type holds a list of exerciseSets. We will generate the listview from this list of exerciseSets. :

To each row, we will need to pass some actions:

The "currentExerciseSet" parameter to pass is just the item from our dynamic list. This item is of data type "exerciseSet" and matches what we have defined as parameters for our exerciseSet component.

We have defined a "tempExerciseData" variable at the component state variable level. Similar to what we did for our "exerciseSet" component, this local state variable will be of type "exercise" and will allow us to temporarily hold our exercise data while we update it and save it. You can also see that we also pass a parameter named "exercise" (of data type exercise) from above. This is because at the top level, we generate a listview of exercises, and each exercise component is passed its respective "exercise" containing its respective "exerciseSets".

The "updateStateAction" that we pass to each "exerciseSet" component will do the following:

Save the current exercise data to the exercise component local state variable,

update the local state variable with the new exerciseSet data

and lastly, execute an action passed from the component above and pass back the tempExerciseData.

The last action (passed from the component above) is the same sequence of events as what we are defining now, only it is done for the workout data instead of being done for exercise data.

Here is the action that we pass from the component above to our exercise component

So to recap: when our "exerciseSet" component is modified, it updates its local component state variable with the most recent data and executes an action passed from the exercise component.

The action passed from the exercise component updates the exercise component local variable named tempExerciseData (type exercise) by saving the current exercise data with the exerciseSet data passed from the exerciseSet component. At this point, the exercise component state variable "tempExerciseData" will hold the new values for this specific exercise. Then we finish this action chain by executing the callBack passed from above (from the workout component) which will do the same and take this new "exercise" data and update the APP STATE VARIABLE at the correct index.

Once the actions are completed, the page rebuilds and the newly updated workout data is passed back down and all textfields are updated (although no change will be visible since they already hold the current values entered by the user.

This method allows you to embed multiple components in one another and to keep everything up to date.

10
13 replies