Дали 3 дня и после можно скинуть даже не полностью готовое.В этом вся соль. Делаете что умеете, а после пытаетесь сделать все остальное. От этого, видимо, будет зависеть ваша ЗП. Вам же не сказали, что нужно заверстать весь макет + анимация + API карты, иначе вы бездарь. Они дали типичный макет для их студии и хотят по максимуму проверить ваши навыки, понять что вы умеете. Но и вправду, не сильно понятно, зачем столько страниц верстать, можно было одну + карта.
Радует что нет адаптива
about:serviceworkers
Becausethis.props
andthis.state
may be updated asynchronously, you should not rely on their values for calculating the next state.
this.setState(
(state) => ({test: !state.test}),
() => console.log(this.state.test)
);
this.state = {...props}
this.state.props.foo
, можно будет обращаться через this.props.foo
.Может ли опыт на React Native считаться одновременно опытом на обычном React? Они настолько похожи?Я бы сказал, процентов на 60. Там нет CSS в традиционном понимании и свои правила раскладки, но то, что касается JS вполне транслируется в браузер - архитектура приложения, паттерны React и т.п. Система сборки там тоже своя и нет заморочек браузерного рендеринга.
const
вместо let
для определения переменных которые не переопределяются в коде. Это помогает снизить когнитивную нагрузку с человека читающего код и негласный стандарт в React разработке.{
isModal
? <Route path="/auth" component={AuthPopup} />
: null
}
{isModal && <Route path="/auth" component={AuthPopup} />}
function mapDispatchToProps(dispatch) {
return {
autoLogin: () => dispatch(autoLogin()),
getBrowser: () => dispatch(getBrowser()),
getMedia: () => dispatch(getMedia())
}
}
const mapDispatchToProps = {
autoLogin,
getBrowser,
getMedia,
};
& label {}
& input {}
& span {}
import {combineReducers} from 'redux';
import photoReducer from './photoReducer';
import authReducer from './authReducer';
import globalReducer from './globalReducer';
export default combineReducers({
photoReducer, authReducer, globalReducer
})
import {combineReducers} from 'redux';
import photo from './photoReducer';
import auth from './authReducer';
import global from './globalReducer';
export default combineReducers({
photo,
auth,
global,
});
return e === 'invalid-email' ? 'Неверно указан e-mail'
: e === 'user-not-found' ? 'Указанный e-mail на найден'
: e === 'wrong-password' ? 'Неверный пароль'
: e === 'email-already-in-use' ? 'Указанный e-mail уже используется'
: e === 'network-request-failed' ? 'Нет подключения к интернету'
: e === 'operation-not-allowed' ? 'Произошла ошибка, попробуйте снова'
: e === 'popup-closed-by-user' ? 'Окно авторизации закрыто пользователем'
: e === 'account-exists-with-different-credential' ? 'Аккаунт уже существует с другими данными, используйте другой способ авторизации'
: e
switch case
import {SET_ACTIVE, CHANGE_VALUE, SET_DEFAULT, UPLOAD, UPDATE_IMAGE, SET_IMAGE_ERROR, SET_LIKE, SET_COMMENT, ADD_ARTICLE_SUCCESS, FETCH_ARTICLES_START, FETCH_ARTICLES_SUCCESS, FETCH_ARTICLES_ERROR} from '../actions/actionTypes';
import {
SET_ACTIVE,
CHANGE_VALUE,
SET_DEFAULT, UPLOAD,
UPDATE_IMAGE,
SET_IMAGE_ERROR,
SET_LIKE,
SET_COMMENT,
ADD_ARTICLE_SUCCESS,
FETCH_ARTICLES_START,
FETCH_ARTICLES_SUCCESS,
FETCH_ARTICLES_ERROR,
} from '../actions/actionTypes';
function mapStateToProps(state) {
return {
browser: state.globalReducer.browser
}
}
const mapStateToProps = state => ({
browser: browserSelector(state),
});
$(document).ready(function(e) {
// показываем картинку. Отменяем события для формы
var port = $('.port').css('display','none');
$("#text").change(function () {
$('#sendFormNews').submit(function(){return false;});
port.css('display','block');
$('.uploadIcon').css('display','none');
});
});
// вешаем слушателя
window.addEventListener('load', function(e) {
// откуда пришла картинка
let input = document.querySelector("#text");
// где показать
let windowPrevImg = document.querySelector('#image_upload_preview');
// наша форма для отправки
let sendFormNews = document.getElementById('sendFormNews');
// функция для страховки
function uploadPasteImage()
{
// еще один слушатель - вешаем на submit - валидим форму один словом. (у меня аякс валидация выше)
sendFormNews.addEventListener('submit',(e) => {
// конвертим нашу строку base64 - говорим что это файл
function dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
//отдаем результат
return new File([u8arr], filename, {type:mime});
}
// вытягиваем base64 с картинки/прелоада
var pasteImage = windowPrevImg.getAttribute('src');
// скармливаем функции да бы получить нужный нам файл да бы обьяснить серверу что это файл
var file = dataURLtoFile(pasteImage, input.value);
// юзаем FormData https://developer.mozilla.org/ru/docs/Web/API/FormData
// в качестве аргумента передаем нашу форму
var fd = new FormData(sendFormNews);
// ищем нужное нам поле в форму и передаем туда наш полученный файл, который мы получили ранее
fd.append('News[image]',file);
// дальше дело техники
// вызываем
var request = new XMLHttpRequest();
// говорим куда и как
request.open("POST", window.location.href);
// загружаем "если" делай то то
request.onload = function(oEvent) {
window.location.replace("/cabinet/my-news");
} else {
console.log("Error " + request.status + " occurred when trying to upload your file.<br \/>");
}
};
// отправляем
request.send(fd);
});
// события для копирования
input.addEventListener("paste",function(event){
let items = (event.clipboardData || event.originalEvent.clipboardData).items;
for (index in items) {
let item = items[index];
if (item.kind === 'file') {
let blob = item.getAsFile();
let reader = new FileReader();
reader.onload = function(event){
windowPrevImg.setAttribute('src', event.target.result);
};
reader.readAsDataURL(blob);
}
}
});
}
// инициализируем нашу функцию
uploadPasteImage();
});
pluginOptions: {
'style-resources-loader': {
preProcessor: 'scss',
patterns: [
path.resolve(__dirname, 'src/scss/_variables.scss'),
path.resolve(__dirname, 'src/scss/_mixins.scss'),
],
}
},
css: {
loaderOptions: {
sass: {
data: `
@import "@/scss/_variables.scss";
@import "@/scss/_mixins.scss";
`,
}
}
},
DONE Compiled successfully in 1704ms 15:06:07
App running at:
- Local: localhost:8080