Я новичок в React Boilerplate и использую контейнеры и саги для получения начальных данных страницы. Я столкнулся с двумя проблемами при реализации этого.
UsersPage\index.js
// imported all sagas, etc
export function UsersPage({
dispatch,
usersPage,
onGetUsers,
onChangeSearch,
onSetActive,
}) {
useInjectReducer({ key: 'usersPage', reducer });
useInjectSaga({ key: 'usersPage', saga });
onGetUsers();
return (...);
}
UsersPage.propTypes = {
dispatch: PropTypes.func.isRequired,
usersPage: PropTypes.object,
onGetUsers: PropTypes.func,
onChangeSearch: PropTypes.func,
onSetActive: PropTypes.func,
};
const mapStateToProps = createStructuredSelector({
usersPage: makeSelectUsersPage(),
});
function mapDispatchToProps(dispatch) {
return {
dispatch,
onGetUsers: () => dispatch(getUsers()),
onChangeSearch: evt => dispatch(changeSearch(evt.target.value)),
onSetActive: active => dispatch(setActive(active)),
};
}
const withConnect = connect(
mapStateToProps,
mapDispatchToProps,
);
export default compose(withConnect)(UsersPage);
UsersPage\actions.js
...
export function getUsers() {
console.log('action getUsers');
return {
type: constants.GET_USERS,
};
}
...
UsersPage\saga.js
export function* getUsers() {
console.log('saga getUsers');
try {
const response = yield call(api.users.getAll);
yield put(
getUsersSuccess({
users: response.data.data,
}),
);
} catch (err) {
const error = err.response.data.message;
yield put(getUsersFail(error));
}
}
export default function* usersPageSaga() {
yield takeLatest(constants.GET_USERS, getUsers);
}
Когда я впервые загрузил страницу, журнал консоли показывает следующее:
action getUsers
saga watcher
Однако, когда я перешел на другую страницу и затем перешел на эту страницу:
action getUsers
saga worker getUsers
ПРОБЛЕМА 1
Кажется, что при первой загрузке средство отслеживания саги вызывается позже, чем действие (getUsers). И, таким образом, он терпит неудачу при первой загрузке, но при последующей загрузке рабочий саги вызывается просто отлично. Как я могу убедиться, что saga watcher вызывается первым перед действием?
ПРОБЛЕМА 2
Поскольку действие (getUsers) находится внутри рендера, его вызывают каждый раз, когдаесть обновление. Поэтому, когда getUsers возвращают и применяют новые данные в редуктор, рендеринг вызывается снова и снова вызывается действие (getUsers), вызывая бесконечный цикл. Что мы должны сделать или как правильно загрузить исходные данные в контейнер?