• Почему первый респонс null?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Алексей Самсонов дело говорит. Нужно идти по массиву данных, когда он есть, либо когда вместо него "начальное состояние" = пустой массив.
    Судя по вашему вопросу, вам проще делать проверку, что если this.props.data.length есть, то рисуй шаблон, если нет - null

    renderTemplate(data) {
      return data.map(item => .... )
    }
    render() {
     ...
    { this.props.data.length ? this.renderTemplate(this.props.data) : null }
     ...
    }
    Ответ написан
    3 комментария
  • Нужна лучшая практика что бы убрать писанину в action?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Сначала тоже казалось "писанина", смотрел в сторону разных middleware'ов и т.д.
    А потом понял - что тут проблемы лично для меня никакой нет. Открываешь старый проект, на котором нашли баг/нужно что-то добавить - и вот оно, все просто по полочкам: есть действие пользователя -> есть action creator -> есть action с определенным типом -> есть reducer ... Достаточно 10 минут, чтобы освежить в памяти "что откуда и куда", поэтому я решил не придумывать и не усложнять.
    Ответ написан
    Комментировать
  • Почему родительский метод вызывается сам по себе?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    В onClick нужно передавать функцию-обработчик, а вы передаете функция-обработчик() === результат вашей функции...
    То есть как только кнопка оказывается на странице, сразу же происходит вызов (круглые скобки).

    Пример:
    function myFunc(data) { console.log(data) }
    console.log( myFunc('test') ) => выведеть в консоль 'test'
    console.log( myFunc ) => выведеть в консоль function myFunc ...


    P.S. естественно, сразу возникает вопрос - как передать функцию + аргумент... Вам нужен либо метод bind, либо анонимная функция... Есть у разных подходов плюсы-минусы, но я тем не менее люблю использовать data-аттрибуты для этого.. тогда при передаче функции обработчик, у меня в event.target.dataset - есть все что нужно.

    P.P.S. когда возникают такие вопросы, значит нужно идти и копать основы, так как в дальнейшем только сильнее будет усиливаться непонимание между функциями, аргументами, полями свойств в props'ax и так далее... Начать по теории, рекомендую отсюда: https://learn.javascript.ru/function-basics, затем: https://learn.javascript.ru/introduction-browser-events
    Ответ написан
    1 комментарий
  • Как правильно выполнять ajax-запросы в react-router?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Запрос должен находиться либо в componentDidMount, либо в componentWillMount.
    Зачем вам componentDidUpdate?

    P.S. недавно меня спрашивали тоже самое, и если у вас проблема в том, что не "происходит" componentDidMount при изменении параметра роута, то здесь нужно использовать componentWIllReceiveProps(!)

    Пример: <Route path='/articles/:id' >
    Вы открываете браузер по URL адресу: /articles/1
    У вас в componentDidMount происходит вызов (например: getArticles(this.props.params.id)

    Затем вы кликая по ссылке, изменяете URL на /articles/2 и ожидаете что произойдет componentDidMount ? Нет, не произойдет, так как роут ('/articles/:id') не изменился, следовательно не было "демонтирования" и "примонтирования" компонента. Зато случилось "изменение props" в компоненте (того самого this.props.params.id), следовательно это можно обработать в componentWillReceiveProps
    Ответ написан
    3 комментария
  • Angular 2 и Redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Некоторое время работал с React и Redux, скажу честно, довольно прикольная вещь, но вот каких то огромных плюсов в использовании Redux я не увидел.

    1) Не увидели относительно чего? Относительно flux / mobx / etc.. ?
    2) Или просто Redux vs setState для всех данных в приложении? (сарказм) Это я к чему, у вас было либо маленькое приложение (очень маленькое), либо вы чего-то не поняли. Если же относительно п.1 - то дополните вопрос
    Ответ написан
  • ComponentWillMount vs ComponentDidMount, где лучше делать XHR к API?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Делайте в didMount, а по поводу:
    если в DidMount то контент может на некоторое время показаться без данных из сервера, или я не прав

    Вы правы, но для этого в шаблоне сделайте: если данных нет - пусто, если данные есть - рендери.. В таком случае для юзера это все будет выглядеть как загрузка страницы...
    Еще лучше, сразу крутить preloader например, и тд.
    Ответ написан
    Комментировать
  • Почему в React созданные функции(методы) вызываются без аргументов?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    // для примера обе переменные (store и dispatch) объявлены в той же области видимости
    // на самом деле их нет в вашем файле компонента
    // Так как функция connect вызывается "где-то там, где они доступны"
    // вы имеете к ним доступ
    let dispatch = () => console.log("dispatch")
    let store = { user: { name: 'Mike', age: 15 }, data: [1,2,3] }
    
    function connect(mapStateToProps, mapDispatchToProps) {
      console.log(mapStateToProps(store))
    }
    
    function mapStateToProps(storeFromClosure) { // здесь оказывается глобальный store доступный из замыкания
      return {
        myData: storeFromClosure.data 
      }
    }
    
    connect(mapStateToProps, null)
    Ответ написан
  • Как кастомизировать сторонний компонент React?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Сторонний компонент, это обычно всего лишь "вьюха". Хорошие компоненты, таковыми и являются (пример) (react virtualized)

    Чтобы передать в него свойства - мы просто передаем свойства. Опять же, в качестве примера (react select 2). Передаем в него, например, options.
    Так же, у этого "хорошего" компонента, на изменение автором задуман onChange..
    <Select
    	name="form-field-name"
    	value="one"
    	options={options}
    	onChange={this.setUser} // тот самый onChange
    />

    Уже в нем можно смело "дергать" экшен-крейтор родителя, банально:
    // текущий компонент
    setUser(e) { this.props.setUser(e.target.value) }
    // родитель
    setUser(id) { this.props.actions.setUser(id) } // вызов redux action-creator


    В любом случае, вариантов обратится из потомка к родителю всего два. Причем первый используется в 90% случаев - это передать в props функцию-обработчик.
    Второй вариант, созданием компонентов-оберток используется реже и обычно уже на каких-то замороченных ситуациях.
    Ответ написан
    Комментировать
  • "Warning: Each child in an array or iterator should have a unique "key" prop." Как исправить?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Ошибка в том, что вы не передаете key, но пытаетесь его установить в
    renderDistrict(item, key)
    У вас функция принимает 2 аргумента, а вы передаете только один здесь:
    this.renderDistrict(item)

    Тем не менее, так как у вас есть id ваша задача решается так:
    renderDistrict(item) {
         return (
            <tr key ={item.id} className="districts">
                <td>{item.id}</td>
                <td>{item.name}</td>
            </tr>
         )
    }


    p.s. для продуктивного изучения react советую подтянуть знания javascript'a
    Ответ написан
    2 комментария
  • Какой необходимый уровень знаний для junior React.js Разработчика?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    UPDATE: реальные тестовые задания и разборы здесь, ответы на все вопросы из поста в моем блоге об обучении react.

    не включая основы js

    Извините, но стандартная задача, про "напишите функуцию add, которая при вызове add(1)(2) вернет 3" - многих положила на лопатки =) Поэтому будьте готовы..

    React
    0) Какую проблему решает react ?
    1) Мгновенно ли срабатывает setState? Если нет, то как выполнить код, который 100% выполнится после того, как новый state будет установлен?
    2) Зачем многие постоянно пишут в constructor: this.FUNCTION_NAME = this.FUNCTION_NAME.bind(this) и отсюда вопрос вытекает чему равно this в разных местах вашего компонента...
    3) в каких методах жизненого цикла стоит выполнять xhr запросы? В каких стоит "обновлять state на основе props"?
    4) Что будет если вызвать this.setState в render методе компонента?
    5) зачем нужен componenWIllUnmount, приведите пример..
    6) Контролируемые, не контролируемые компоненты
    7) Как организовать роутинг в реакт приложении? (ответ: взять react-router - подходит, но было бы круто, если бы вы рассказали, как он примерно работает)*
    8) Зачем нужны propTypes? Что происходит с ними в production сборке?
    9) Как можно удобно "отлаживать" чужой код приложения, написанного на react (намек в сторону React devtools)
    ...

    Redux
    0) Какую проблему решает redux?
    1) Зачем многие создают типы действий NAME_REQUEST / NAME_SUCCESS ? А заодно, что такое "действие", а что такое "создатель действия"...
    2) Что такое редьюсер? Можете написать простой редьюсер без react/redux?*
    3) Для чего нужен redux-thunk? Как он работает? Напишите (можно псевдокод) асинхронный создатель действия (либо, если надоело говорить "терминами" - асинхронный aciton)
    4) Как компоненты приложения получают "пропсы" из "стора"?*
    5) Можно ли (и считается ли это нормальным) использовать state, если используется Redux?
    6) Почему в reducer'ax мы возвращаем новые объекты? Приведите пример, когда вы возвращаете новый объект, а когда тот же самый.
    6.5) А так же, "как в js вообще это работает?". Например:
    let obj1 { name: 'Test', age: 100 }
    let obj2 = obj1
    obj2.name = 'Test_new'

    Что будет в obj1, почему? В каких случаях объекты могут быть равны?
    7) Что возвращает функция connect (из react-redux)?
    ...

    Общее:
    0) package.json
    1) Webpack, gulp, etc...
    2) node.js
    3) promise

    Что-нибудь практическое:
    1) Как бы вы валидировали форму, если ошибки валидации приходят после submit'a ее на сервер..
    2) Почему не работает следующий код, сделайте чтобы работало
    ...
    На истину не претендую, но такие вопросы имели место быть на собеседованиях. В беседе можно многое разузнать дополнительными вопросами и так далее. Так же, если часть вопросов вам неизвестна - не беда, многие и на половину ответить не могут.

    p.s. возможно дополню...
    p.p.s. звездочкой отметил, на мой взгляд не самые необходимые для junior-собеседования вопросы.
    Ответ написан
    31 комментарий
  • Почему не импортируются константы?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Потому что вы сделали именованный экспорт, следовательно подключать нужно:
    import { Constants } from './Constants';
    Ответ написан
    Комментировать
  • Почему теряется this?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    С версии 0.14 при записи extends ... Component реакт больше не "автобиндит" this.
    Если использовать React.createClass - будет. Но лучше просто bind'ить необходимое в constructor'e
    Ответ написан
    Комментировать
  • Какая правильная организация react-redux приложения?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Не понял о каком наследовании идет речь, а так же последние абзацы, остальное кажется достаточно понятным, поехали.

    Есть меню(не навигация, а просто набор плюшек, к примеру добавить заметку) и сама область где отображается эта заметка.

    Почему этот "набор плюшек" не завязать на "навигации" ?
    То есть "добавить заметку" -> /add, редактировать -> /edit/:id .. ? В любом случае, вы сами пишите о 2х областях, которые есть на всех страницах, значит у вас должен быть родительский компонент, в котором рендерится "шапка (меню это или нет, не важно) + рабочая область"

    Получается, если вы все же за идею с роутером, то примерный код будет таким:
    App.js
    ...
    <HeaderContainer /> // (или тупой <Header />)
    { this.props.children }
    ...


    Внутри children, само собой разумеется - то, что возвращает ваш роутинг, значит, код роутера примерно такой:
    ...
    <Route path='/add' component={AddContainer} />
    <Route path='/edit/:id' component={EditContainer} />
    ...


    Когда я говорю "контейнер", значит я подразумеваю (как и все остальные), что это компонент, который присоединен к redux ( то есть
    connect(mapStateToProps,mapDispatchToProps)(имя_компонента)
    ).

    Таким образом, мы уже решили вашу задачу про: Меню при вызове запускает компонент конкретной задачи. тот отправляет результат на рабочий стол и там оно хранится , так как у нас в меню все сделано с помощью Link из react-router'a, и наша рабочая область изменяется вместе с URL-адресом браузера. Если есть необходимость, все клики по меню "прогонять" через ActionCreators (AC) выполняя какие-то дополнительные действия, или просто "для порядка" - то вы можете использовать внутри ваших AC push из react-router-redux, выглядит это обычно так:
    dispatch(push('/newUrl'))

    Если вы с реакт-роутером не хотите пример делать, то принцип все равно будет такой же, только вместо URL адреса, у вас должен быть другой признак, на основе которого будет создаваться рабочая область.

    ---
    И еще. думаю вынести все данные(пункты меню к примеру) в отдельный файл(этакий недосервер)
    Где с ним лучше общаться? использую react-redux

    Определенно будете общаться в ваших функциях-создателях-действий, так как это же будет асинхронный запрос за json-файликом, а значит другого места быть не может. Если опустить правильные названия, то ваша область работы с файлом - actions.
    ---

    Как уже сказано, в конце не пойму о чем вы пишите... Структура "ответа с сервера" ? или о чем речь? Зачем вам компонент, который будет приводить структуру в нужный вид? и тд.

    ---
    Напоследок:

    Да и мне примеры вовсе не нужны. хочу для начала своих шишек набить.
    НО точно не хочу пару месяцев пилить проект(бесконечно усложняющаяся toDo) а потом понять что привык делать так как не надо.

    Никакого привыкания "делать, как не надо" - не бывает. Вы сначала делаете так, как считаете наилучше возможным, в процессе, что-то подпиливая, потом приходит озарение/совет - вы понимаете, что так будет лучше и делаете дальше. Если программист знает как "сделать лучше", но при этом делает "как привык" то грошь ему цена.
    Ответ написан
    8 комментариев
  • Какой метод необходимо вызвать при изменении props в дочернем компоненте?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Когда у вас 1й раз происходит "и то и другое" - это ваш componentDidMount + render (у Child)
    Когда вы "нажимаете на кирпичик", то у вас componentDidMount уже не происходит (судя по коду, так как компонент у вас не удаляется из DOM и не появлется там снова). Но так как вы по нажатию меняете у родителя что-то, и это что-то прокидываете в потомка - значит "ему пришли новые props", следовательно используйте componentWillReceiveProps, где в nextProps - будет то что вам нужно.

    Документация про lifecycle methods

    p.s. проверьте, у вас в тексте примера есть someId и sometId (опечатка)
    Ответ написан
    2 комментария
  • Как решить проблему перезагрузки страницы react-router?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Где-то отвечал на тостере, не могу найти вопрос, но ответ кроется здесь в главе, если у вас не грузится bundle, а скорее всего так и есть.
    Если нет - покажите ошибку в консоли браузера.
    Ответ написан
  • Со знанием какого MVC фреймворка больше шансов найти работу в русскоязычном сегменте?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Всегда есть возможность посмотреть сайты с вакансиями! Вам нужно поанализировать hh.ru и moikrug.ru
    По моим наблюдениям, годных вакансий на удаленку, на Моем круге всегда было больше.
    p.s. фильтры по удаленке настраиваются на обоих сайтах.
    Ответ написан
    Комментировать
  • Как в react-redux реализовать вызов метода в ответ на изменение стейта?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Добрый день.

    Представим ваш action creator (функцию), которая на success возвращает успешную авторизацию, например:
    $.ajax(url...
      success(data) { dispatch({type: AUTH_SUCCESS, data }) })


    Кто мешает сделать так?
    $.ajax(url...
      success(data) { 
        dispatch({type: AUTH_SUCCESS, data }) 
        loadUserCart(data.user_id) // <- еще один action creator
    })

    Суть уже понятна? Мы после успешной авторизации юзера, вызываем сразу же следующий экшен-крейтор:
    function loadUserCart(id) {
      return (dispatch) => {
        
        dispatch({ type: CART_REQUEST }) // получается, это событие вызовется сразу после успешной авторизации, практически мгновенно
    
        
        $.ajax(urlForCartUpdate...
          success(data) { 
            dispatch({type: CART_SUCCESS, data })
        })  
      }
    }


    Далее вы в компоненте с корзиной, настраиваете показ прелоадера, и вуаля! Получается, для юзера, без задержек, как только он авторизовался - у корзины будет крутиться прелоадер. Юзеру все понятно, он занимается своими делами. Как только "данные подъехали" - вы скрыли прелоадер и показали ему необходимые данные по корзине.

    нужно сначала сделать AJAX-запрос, а по его результатам уже рендерить корзину

    Именно это мы и сделали.

    P.S. не знаю, требуется ли это, но на всякий случай укажу, что чтобы сделать прелоадер в шаблоне, вам нужно в редьюсере корзины создать какое-нибудь поле (флаг), например isLoading и устанавливать его в true когда получите action с типом CART_REQUEST, и false для CART_SUCCESS. Таким образом, вы сможете сделать банальный if в шаблоне рендера и показывать либо разметку прелоадера, либо разметук с данными корзины.

    === вторая часть ===
    В компонентах-контроллерах есть только функция connect() со своими функциями-аргументами, которые передают данные в представление. Как-то реагировать на изменения состояния такие компоненты не умеют (я ведь не ошибаюсь в этом?).

    Еще как умеют, в этом и суть. Вы в mapStateToProps передаете в общем случае:
    {
      ваше_название_поля: reduxStore.название_редьюсера
    }

    В частном случае, может выглядеть так:
    function mapStateToProps(state) {
      return {
        rate: state.rate,
      }
    }


    После того, как вы "подписались" на изменения в state.rate, (а это, если говорить об частном случае, скорее всего reducer с названием rate), ваш "приконекченный" компонент всегда будет получать новые props при изменении в редьюсере. Следовательно, будет вызываться функция render. Само собой - можно хоть сколько "редьюсеров подключить" к одному компоненту.

    Имейте ввиду, что все здесь написано для понимания простым русским языком, на самом деле, так как вы используете компонент Provider на самом верхнем уровне вашего приложения, он прокидывает необходимые props вниз. Ваши connect(Компоненты) умеют реагировать на изменение необходимых props => реакт вызывает рендер, так как "пришли новые props".
    Ответ написан
    2 комментария
  • Чтение и перенос json данных в таблицу ES6?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    К предыдущему вопросу добавлю, так как вижу тэг 'react'

    1) вам нужно осознать, что раз приходят новые данные, значит у нас есть какой-то "изменяемый кусок", следовательно - необходимо будет использовать state, следовательно нужно задать this.state в constructor, с какими-то начальными данными, например "пустой массив"

    2) нужно выполнить запрос после того, как компонент окажется на странице, для этого подойдет метод жизненного цикла - componentDidMount

    3) в момент componentDidMount вы может выполнить запрос с помощью любой библиотеки, например jquery из ответа выше, но чаще с реактом используют npm-fetch, axios и подобные.. а можно и вообще XHR объектом стандартным обойтись...

    4) после выполнения запроса, на успешный ответ, вы должны изменить state, то есть вызвать this.setState

    5) после выполнения шагов выше, реакт вызовет метод render - в котором вы уже отрисуете таблицу, на основе ваших данных из state
    Ответ написан
  • Выбор js фреймворка (технологии) для crm?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Как уже не раз здесь обсуждалось, сейчас из "трендов" 3 технологии: react, angular, vue
    Выбирайте ту, которая больше по душе...
    По популярности уже сложно сказать, где больше/лучше, но думаю по angular больше различных материалов и рецептов, чем по react/vue + желаемый вами material и angular от одной конторы.
    Ответ написан
  • Redux-Form. Как получить formValueSelector формы, когда имя формы передается в пропсах?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Из примера непонятно, что мешает передавать вместо строки 'selectingFormValues' - переменную, в которой будет название формы?

    Например в switch case операторе, в зависимости от props устанавливать необходимое значение в переменную и ее передавать в formValueSelector(моя_переменная)
    Ответ написан