React Native text input forms simplified with useReducer hook
Recently I wanted to build a text input form that looks as follows:
The main functionality consists of the following features:
- Inserting a question name in the question title text input
- Inserting choices for a given question in choice text inputs
- Creating new choice text inputs by pressing the plus button
I decided that this is a good use case for useReducer
hook, since I needed to create text input handlers dynamically and store the input values in the state.
In this article, I’d like to show you how I created a custom hook for this form and utilised it in the above component.
First, we’ll walk through the reducer for useReducer
hook. Then we’ll look into the custom hook for our form. Finally, we’ll implement the form component using our custom hook.
Reducer
First, we set up an initial state for the reducer. It contains:
- questionTitle: Title of the question.
- choiceInputs: Unique id, value, and placeholder for each choice input. We pre-populate it with two items, because we want each question to have at least two choices.
- nextChoiceId: A unique id for the next choice input to be created.
In the reducer we handle three actions:
- QUESTIONS_TITLE_CHANGED: Changes the question title.
- CHOICE_VALUE_CHANGED: Changes a choice value based on the provided id.
- NEW_CHOICE_ADDED: Creates a new choice input item and increments the
nextChoiceId
.
Custom hook
Let’s use the reducer we’ve created with useReducer
hook in our custom hook and expose state
and dispatch
.
Form Component
Let’s use our custom hook in the form component.
The component simply consumes the state and dispatches actions on certain events. All of the state updates are handled separately in our custom hook.
Summary
By properly utilising React hooks, the implementation of text input forms in React Native can be made simple and maintainable.
You can find the full example project here: https://github.com/aarkalyk/react-native-polls-api-example.
If you have any questions, please leave them in the comments.