Search code examples
reactjsreduxredux-thunkredux-toolkit

Using React and Redux, how would you clear an input field after a successful redux-thunk completion?


Let's say you are using react and redux and you have the following elements on a page:

  • Input field to write something
  • A save button to write your text async to the DB

The expected flow is that the save button should dispatch a save redux thunk to handle the async behaviour of the save. So far, so good.

But there's an extra tricky requirement:

  • Upon save success, the input should be cleared.

I think that there are a couple of ways to handle this:


OPTION 1

  • Add the controlled input state to your Redux store

This is the easiest one. Basically you'll add the input state to your Redux store and when you thunk dispatch the SAVE_SUCCESS action, your reducer will respond with something like this:

SAVE_SUCCESS(state, action) {
  state.inputValue = '';
}

The downside of this is that you'll have to dispatch an action on every key stroke, and that is going to flood your Redux devTools inspector.


OPTION 2

  • Have a controlled input using React local state
  • Pass an clearInput function (using useCallback) to your save thunk

Something like this:

const [inputValue, setInputValue] = useState('initialVale');
const clearInput = useCallback(() => setInputValue(''),[]);

const onClick = dispatch(saveThunk({clearInput});

So, from the thunk you would do something like:

const { clearInput } = thunkProps;
await saveToDB();
clearInput(); // THIS COMES FROM THE thunkProps

OPTION 3

  • Same as option 2 but with an uncontrolled input (so, no state at all)
  • Pass the input ref element to your thunk

So, from the thunk you would do something like:

const { inputRef } = thunkProps;
await saveToDB();
inputRef.current.value = '';

QUESTION

Which one would you go for and why? And also, is there a better approach to this that I'm not aware of?


Solution

  • I would go for awaiting the promise from the thunk in the component, and setting component state there, as shown in our tutorials:

    Example:

      const handleKeyDown = async e => {
        // If the user pressed the Enter key:
        const trimmedText = text.trim()
        if (e.which === 13 && trimmedText) {
          // Create and dispatch the thunk function itself
          setStatus('loading')
          // Wait for the promise returned by saveNewTodo
          await dispatch(saveNewTodo(trimmedText))
          // And clear out the text input
          setText('')
          setStatus('idle')
        }
      }