Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

task-99: feat: внедрить OAuth #108

Merged
merged 8 commits into from
Sep 22, 2021
Merged

task-99: feat: внедрить OAuth #108

merged 8 commits into from
Sep 22, 2021

Conversation

andreyvolokitin
Copy link
Contributor

No description provided.

Comment on lines -75 to +80
state = { ...state, ...action.payload };
Object.assign(state, action.payload);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Антон мне сказал, что с state = { ...state, ...action.payload } - более красиво и читаемо

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я не уверен что это будет работать, там надо мутировать сам state, а тут будет создаваться новый объект

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я понял почему это не работало, надо возвращать новый объект, а не присваивать в state

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В редаксе никогда не надо мутировать стейт, только возвращать новый объект)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В голом редаксе да. В тулките по дефолту immer включен, и уже был мутирующий код в редьюсерах на его основе. Ещё 1 причина разбираться с тем, как работает голый редакс

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хотя в тулките так можно работать, там же immer

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Что касается Object.assign, то лучше спреды юзать. Стильно, модно, молодёжно и поведение супер ожидаемое

@@ -0,0 +1,23 @@
import { useCallback, useState } from 'react';

export default function useProgress(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Поясни, пожалуйста, что этот хук делает

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Создаёт функцию запроса через useCallback и флаг ожидания через useState, возвращает их. Флаг ожидания используется для отображения состояния запроса, например для показа спиннера в кнопке, функция используется для запуска запроса, например в onClick кнопки

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏻
Выносить такие штуки в хук — хорошая идея, красавчик)

Copy link

@kotosha-real kotosha-real left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Есть пара вопросов по userReducers, а так очень хороший пр)

} catch (e) {
throw new Error(e);
} finally {
window.history.replaceState(null, document.title, window.location.pathname);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


А зачем?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Там в url код остаётся, его надо убрать. Я думал как это лучше сделать, и когда (может лучше сразу же до начала авторизации его убрать, но тогда если авторизация будет неуспешна, а этот параметр был на самом деле вообще для другого, то получается уберём чужой параметр)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это не супер критично на самом деле. Но если уже убираем — давай убирать

@@ -33,6 +36,19 @@ function LoginPage({ title }: GenericPageProps): JSX.Element {
console.log('error', translateErrorMessage(err.message));
}
}, []);
const [isOAuthInProgress, startYandexOAuth] = useProgress(async () => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧐
Кажется, что window.location.replace убивает весь шарм неплохого хука — запрос за id будет очень коротким, по сути ты даже можешь не увидеть прогресс

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не таким уж и коротким (on my machine), для доп. шарма я даже ввёл вроде бы бесполезный второй параметр — keepProgress, т.е. он ещё будет показываться пока страница раздумывает перед редиректом, а запрос уже завершён. Ну и редирект в любом случае нужен, как и хук (только я засомневался насчёт него, его вроде бы можно использовать для любого запроса, но если внутри асинхронной функции будут зависимости, которые следовало бы указать в useCallback, то это уже нельзя будет сделать, хотя формально вроде бы уже и не нужно, т.к. единственная зависимость useCallback — сама функция)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если useCallback имеет зависимости, то их нужно туда передать, иначе корректность вычислений внутри функции пострадает. Поинт хороший, юзабельность хука можно дополнить массивом зависимостей (то есть третьим аргументом)

@@ -0,0 +1,23 @@
import { useCallback, useState } from 'react';

export default function useProgress(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏻
Выносить такие штуки в хук — хорошая идея, красавчик)

*/
export default function useProgress(
action: () => Promise<unknown>,
keepProgress = false

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


А в чём юзабельность? Если передать true, то получится вечный спиннер

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут описал: #108 (comment)

Comment on lines 40 to 42
const response = await api.getUser();

return response;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❗️
Такое безболезненно можно сокращать

Suggested change
const response = await api.getUser();
return response;
return await api.getUser();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это сомнительный момент, который я пока не прояснил. return await считается антипаттерном, но не всегда. Надо раз и навсегда с этим разобраться

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вот тут есть о том, когда надо, а когда не стоит)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В конкретно этом случае эти участки кода идентичны, в правиле говорится о том же

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Идентичны, и следуя правилу как бы "неправильны", т.е. надо писать return api.getUser(). Во многих случаях (у нас во всём коде подобные строчки/случаи) это будет вроде как нормально — если мы не обрабатываем ошибки, то возвращаем такой же промис, как и через await, просто он разрешится самостоятельно, а мы его в функции ждать не будем. Исключение когда мы деструктурируем результат const { val } = await api.method(), тут уж точно нужен await.

Но здесь у нас редьюсер, т.е. может ожидается какой-то особый возврат, хотя с await мы тот же промис возвращаем, просто который уже точно зарезолвится. Мне кажется return api.getUser() здесь будет работать?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Сама асинхронная функция ничего не ждёт, с ней просто работаешь, как с промисом, не путай всё в одну кучу)
Насчёт возвращения промиса из api в целом довольно логично, но в таком случае давай везде сделаем консистентно

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну я уже не уверен что не ждёт, не удивлюсь что и ждёт после всего что прочитал, хотя понимаю что скорей всего нет. Буду потом в спецификации смотреть

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Этот момент надо отражать в кодстайле, он довольно неоднозначный. Использовать await только для реальной необходимости. Использовать async если нужно вернуть промис. Даже сложно сразу внятно сформулировать, о чём писать в кодстайле

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хотя сами слова понятные: await — ждёт, async — возвращает промис

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хотя... Это всё как раз это правило и регулирует — no-return-await, может и писать ничего не надо. Просто указать что код как выше писать не надо (ждать и присваивать в переменную а потом её же возвращать)

Comment on lines -75 to +80
state = { ...state, ...action.payload };
Object.assign(state, action.payload);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хотя в тулките так можно работать, там же immer

Comment on lines -75 to +80
state = { ...state, ...action.payload };
Object.assign(state, action.payload);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Что касается Object.assign, то лучше спреды юзать. Стильно, модно, молодёжно и поведение супер ожидаемое

})
.addCase(updateAvatarRequest.fulfilled, (state, action) => {
state.avatar = action.payload.avatar;
})
.addCase(userRequest.fulfilled, (state, action) => {
Object.assign(state, action.payload);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


А какие данные тут подсовываются в стейт? Хочется поменьше Object.assign

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Юзер ложится в ветку стэйта user. Надо определится с конвенциями, мутирующий код мне показался более удобным (не зря он в тулките включен). assign для мутирования, через спред я не уверен как делать мутацию. Ещё аспект единообразие (если оно нужно здесь) — либо везде мутирование, либо везде иммутабельность

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не, давай на мутировании остановимся, просто Object.assign не самый лучший вариант для этого. Он работает, но я провёл быстрый соцопрос в офисе и некоторые ребята не знали, что первый аргумент мутируется

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну спредом насколько я понимаю мутирования не сделать, хотя как по мне тут "чистота конвенций" не стоит того, и можно было бы использовать return {...action.payload}. Т.е. для мутирования объекта не так уж много вариантов помимо assign

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну, тут согласен, все поля менять руками — то ещё удовольствие. Ты выше писал про ошибку, ты с ней разобрался? Всё ок работает?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В целом по этому таску ошибок нет, по стэйту я разобрался (мутация либо return, но return пока не проверял), по самому oauth всё работает, ошибка была при попытке oauth будучи уже залогиненным

Copy link

@kotosha-real kotosha-real left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🕵🏻‍♂️

@andreyvolokitin andreyvolokitin merged commit cc81af9 into dev Sep 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants