Да, вы можете использовать async / await в реагирующих компонентах. Это не плохая практика
Это просто вопрос архитектуры.
Существует множество способов реализации асинхронной логики в приложениях. В небольшом приложении вы можете реализовать асинхронную логику в реагирующих компонентах. Когда ваше приложение вырастет, у вас появятся некоторые проблемы, такие как дублированный код (например, вы хотите получить пользователя из нескольких реагирующих компонентов), составление кода и разбиение кода.
Вы можете использовать redux-thunk https://github.com/gaearon/redux-thunk, redux-saga https://github.com/redux-saga/redux-saga, redux-logic https://github.com/jeffbski/redux-logic или любое другое решение.
Кроме того, вы можете создать свое собственное промежуточное программное обеспечение, например:
const reactions = {};
export const addReactions = signals => {
reactions = { ...reactions, ...signals };
};
export default (signalMiddleware = ({ getState, dispatch }) => next => action => {
if (!action.signal) {
return next(action);
}
if (!reactions[action.signal]) {
throw new Error(`There is no handler for ${action.signal} signal`);
}
reactions[action.signal]({ getState, dispatch, payload: action.payload });
});
Такое промежуточное ПО позволяет реализовать бизнес-логику на отдельном уровне. Например:
import { addReactions } from './path/to/signalMiddleware';
// Describe your Actions for middleware:
const fetchUser = (id) => ({
signal: 'FETCH_USER',
payload: id
});
const anotherAction = () => ({
signal: 'SOME_ANOTHER_ACTION_WITH_USER',
});
// Describe your business logic using middleware:
addReactions({
FETCH_USER: async ({dispatch}, {id}) => {
const user = await fetcher.get(id);
dispatch({
type: 'RECEIVE_USER',
payload: user,
});
},
SOME_ANOTHER_ACTION_WITH_USER: () => {
// do some awesone job :)
}
})
Таким образом, наш компонент реакции может быть:
class User extends Component {
render() {
return <div>{this.props.user.name}</div>
}
componentDidMount() {
this.props.dispatch(fetchUser(123));
}
}
export default connect(state2props, dispatch2props)(User);
Теперь вы можете разделить архитектуру вашего приложения на 3 уровня:
1) Вид - реагирующие компоненты
2) Бизнес-логика - ваше промежуточное ПО
3) Логика данных - ваш редуктор
Между представлением и бизнес-уровнем мы используем определенные действия с полем signal
и без поля type
.
Между бизнесом и логикой данных мы используем действия с полем type
.
Эта архитектура позволяет получить строгое разделение слоев. Эта архитектура полезна в больших приложениях.
В небольших приложениях можно использовать redux-thunk или написать асинхронную логику в реагирующих компонентах.