使用 React 和 Redux,如何在 redux-thunk 成功完成后清除输入字段?

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

假设您正在使用 reactredux,并且页面上有以下元素:

预期的流程是保存按钮应该调度一个 save redux thunk 来处理保存的异步行为。到目前为止,还不错。

但是还有一个额外的棘手要求:

我认为有几种方法可以解决这个问题:


选项 1

这是最简单的一个。基本上,您会将 input 状态添加到您的 Redux 存储中,当您发送 SAVE_SUCCESS 操作时,您的 reducer 将响应如下内容:

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

这样做的缺点是你必须在每次击键时发送一个动作,这会淹没你的 Redux devTools 检查器。


选项 2

像这样:

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

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

所以,从 thunk 你会做这样的事情:

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

选项 3

所以,从 thunk 你会做这样的事情:

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

问题

你会选择哪一个,为什么?还有,有没有我不知道的更好的方法?

我会等待组件中 thunk 的承诺,并在那里设置组件状态,如我们的教程所示:

示例:

  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')
    }
  }

我想马克的答案应该是推荐的。但是,作为另一种方法(并且作为将来给自己的注释),如果您没有使用 createAsyncThunk 函数来创建您的 thunk,您可以指定一个要从您创建的常规 thunk 返回的值你自己。

这是一个非常粗略的示例,但可以解决问题:

import { AnyAction, ThunkAction } from '@reduxjs/toolkit';

type MaybeSuccess = { success: boolean }
type AppThunkMaybeSuccess = ThunkAction<Promise<MaybeSuccess>, RootState, unknown, AnyAction>;


export const someThunk = (): AppThunkMaybeSuccess => async (dispatch, getState) => {
  try {
    dispatch(SOME_THUNK_START());
    const data = await doSomeAsyncStuff(...);
    dispatch(SOME_THUNK_SUCCESS({ data }));
    return ({ success: true });
  }
  catch(err) {
    const error = err as Error;
    dispatch(SOME_THUNK_FAILURE();
    return ({ success: false });
  }
}

然后,在您的组件(发送 thunk 的组件)上,您可以:

const handleSave = useCallback(async () => {
  const { success } = await dispatch(saveThunk());
  if (success) {
    setInputValue('');
  }
},[]);