Reputation: 12189
There is the following component code:
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { RootStateType, AppDispatch} from '../../store';
import { changeTask } from '../../reducers/todo';
import { addTodo } from '../../async-thunks/todo';
import Form from '../../components/form';
import Button from '../../components/button';
import Input from '../../components/input';
const NewTask: React.FC = () => {
const dispatch = useDispatch<AppDispatch>();
const newTask = useSelector((state: RootStateType) => state.todo.newTask);
const onTaskAdd = async (event: React.FormEvent<HTMLFormElement>) => {
const res = await dispatch(addTodo(newTask));
};
const onTaskNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
event.stopPropagation();
dispatch(changeTask(event.target.value));
};
return (
<Form onSubmit={onTaskAdd}>
<Input type="text" value={newTask} onChange={onTaskNameChange}></Input>
<Button type="submit">Submit</Button>
</Form>
);
};
export default React.memo(NewTask);
Also there is a simple async thunk:
export const addTodo = createAsyncThunk('tasks/addTask', async(name: string): Promise<string> => {
const response = await fetch('/api/tasks', { method: 'POST', body: JSON.stringify({ name }) });
return await response.json();
});
As you could see I've just created a simple async thunk, and I'd like to redirect to '/tasks' route from my component after success API request. I want to do it in my component, not async thunk. How should I do it correctly? Problem is to do it after success request; if error, I don't want to do redirect.
Upvotes: 3
Views: 2775
Reputation: 67459
The typical approach would be to await the promise returned by the thunk, and then unwrap it to determine success/failure. From there you can do a history.push()
.
Note that the upcoming Redux Toolkit 1.6 release will have a .unwrap()
method on the returned promise to make it a bit similar:
// now
const resultAction = await dispatch(someAsyncThunk());
try {
unwrapResult(resultAction);
// must be okay
history.push('/some/route');
} catch (err) {
// must have failed
}
// Upcoming RTK 1.6
try {
await dispatch(someAsyncThunk()).unwrap()
history.push('/some/route');
} catch (err) {}
Upvotes: 1
Reputation: 104
You can dispatch some "flag" to store from your thunk upon successful request.
Then in your component using useSelector you should get access to that "flag" from your store.
In useEffect you can use history.push('/tasks') with condition. so it would looks like this:
useEffect(() => {
if(flag) {
history.push('/tasks')
}
}, [flag])
Upvotes: 0