Опыт фронтенд-интервью в июне 2018 года (часть 2)

внешний интерфейс React.js Webpack опрос
Опыт фронтенд-интервью в июне 2018 года (часть 2)

предисловие

Это последняя статья о предварительном интервью в июне, поскольку мой технологический стек — это React, ниже приведены записи некоторых вопросов, заданных интервьюером лицом к лицу~

react

жизненный цикл реакции

МОНТАЖ:

  • mountComponent отвечает за управление getInitialState, componentWillMount, render и componentDidMount в жизненном цикле.

Поскольку getDefaultProps управляется через конструктор, он также выполняется первым за весь жизненный цикл. А mountComponent можно только поражаться, не имея возможности вызывать getDefaultProps. Это объясняет, почему getDefault-Props выполняется только один раз.

ПОЛУЧИТЬ_ПРОПС:

  • updateComponent отвечает за управление componentWillReceiveProps, shouldComponent-Update, componentWillUpdate, render и componentDidUpdate в жизненном цикле.

РАЗБОРКА:

  • unmountComponent отвечает за управление componentWillUnmount в жизненном цикле.

Порядок, в котором выполняется жизненный цикл компонента в различных состояниях.

  • Когда компонент монтируется впервые, getDefaultProps, getInitialState, componentWillMount, render и componentDidMount выполняются в указанном порядке.
  • Когда компонент размонтирован, выполните componentWillUnmount.
  • Когда компонент перемонтируется, getInitialState, componentWillMount, render и componentDidMount выполняются по порядку, но getDefaultProps не выполняется.
  • Когда компонент визуализируется снова, компонент получает состояние обновления, а затем выполняются componentWillReceiveProps, shouldComponentUpdate, componentWillUpdate, render и componentDidUpdate по порядку.

Связь между жизненным циклом реакции и setState

  • setState Новички в React часто пишут такой код, как this.state.value = 1, что совершенно неверно.

Никогда не изменяйте this.state напрямую, это не только неэффективно, но и может быть заменено последующими операциями.

setState реализует обновления состояния через механизм очереди. При выполнении setState состояние, которое необходимо обновить, будет объединено и помещено в очередь состояний вместо немедленного обновления this.state Механизм очереди может эффективно обновлять состояние пакетами. Если значение this.state изменяется напрямую без setState, состояние не будет помещено в очередь состояний.При следующем вызове setState и объединении очереди состояний ранее измененное состояние будет проигнорировано, что приведет к непредсказуемым ошибкам.

Поэтому для обновления состояния следует использовать метод setState.В то же время React также использует механизм очереди состояний для реализации асинхронного обновления setState, чтобы избежать частых и повторных обновлений состояния.

Соответствующий исходный код выглядит следующим образом:

// 将新的 state 合并到状态更新队列中 
var nextState = this._processPendingState(nextProps, nextContext); 
// 根据更新队列和 shouldComponentUpdate 的状态来判断是否需要更新组件
var shouldUpdate =  this._pendingForceUpdate ||
                    !inst.shouldComponentUpdate ||
                    inst.shouldComponentUpdate(nextProps, nextState, nextContext)

  • Вызов setState в жизненном цикле

WechatIMG2.jpeg-243.2kB

  • Что произойдет, если мы выполним метод setState в componentWillMount? Компонент обновляет состояние, но отрисовывается только один раз. Поэтому это бессмысленное выполнение, состояние при инициализации можно поместить в this.state.

  • Что произойдет, если мы выполним метод setState в componentDidMount? Компонент, конечно, снова обновится, но рендерить компонент дважды во время инициализации не очень хорошо. Но реальная ситуация такова, что есть некоторые сцены, которые должны нуждаться в setState, Например, при вычислении положения или ширины и высоты компонента вы должны позволить компоненту сначала отрендериться, обновить необходимую информацию, а затем снова отрендерить.

  • Что произойдет, если мы выполним метод setState в componentWillUnmount? Повторный рендеринг не запускается, поскольку все очереди обновлений и состояния обновлений сбрасываются до нуля, а общедоступные классы очищаются, завершая операцию размонтирования компонента.

  • Риск вызова цикла setState

При вызове setState фактически выполняется метод enqueueSetState, и очереди обновления partialState и _pending-StateQueue объединяются, и, наконец, обновление состояния выполняется через enqueueUpdate.

Метод PerformUpdateIfNecessary получит _pendingElement, _pendingStateQueue, _pending-ForceUpdate и вызовет методы ReceiveComponent и updateComponent для обновления компонента.

если вshouldComponentUpdateилиcomponentWillUpdateЕсли в методе вызывается setState, в это время this._pendingStateQueue != null, метод PerformUpdateIfNecessary вызовет метод updateComponent для обновления компонента, но метод updateComponent вызоветshouldComponentUpdateа такжеcomponentWill- Updateметод, что приводит к вызову цикла, что приводит к сбою браузера после заполнения памяти, как показано ниже.

WechatIMG3.jpeg-77.2kB

В чем разница между pureComponent и компонентом

Когда в родительском компоненте есть несколько дочерних компонентов, изменение дочернего компонента вызовет повторную визуализацию всех дочерних компонентов. Обычно мы используем жизненный цикл shouldComponentUpdate для суждения, но этот жизненный цикл чрезвычайно требователен к производительности, и этот метод не рекомендуется в реакции.

На данный момент мы можем просто имитировать метод shouldComponentUpdate. pureComponent помогает нам реализовать поверхностное сравнение по умолчанию на самом внешнем уровне компонента.

React.PureComponent почти идентичен React.Component, но React.PureComponent реализует shouldComponentUpate() с небольшим отличием свойства и состояния.

Если функция render() компонента React отображает тот же результат с теми же параметрами и состоянием, в некоторых случаях вы можете использовать React.PureComponent для повышения производительности.

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

рассмотрите возможность использования不可变对象для облегчения быстрого сравнения вложенных данных. Кроме того, функция shouldComponentUpate() в React.PureComponent игнорирует дочерние элементы всего компонента. Убедитесь, что все дочерние компоненты также являются «чистыми».

Как отправить асинхронный запрос в жизненном цикле

Как правило, асинхронный запрос отправляется в жизненном цикле componentDidMount(). Поскольку dom, который может понадобиться на данный момент, уже смонтирован в браузере, мы можем получить некоторые нужные нам параметры или сохранить возвращенные данные в теге.

Обратитесь к официальному объяснению componentDidMount

componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.

Что такое компоненты высшего порядка в реакции? Как реализовать компонент более высокого порядка?

В процессе создания компонентов React часто возникают такие сценарии: есть тип функции, которую необходимо разделить между разными компонентами, в это время затрагивается тема абстракции. При разных концепциях дизайна существует множество абстрактных методов, и для React мы будем использовать компоненты более высокого порядка.

Функция высшего порядка — это фундаментальное понятие функционального программирования, описывающее функцию, которая принимает функцию в качестве входных данных или выводит функцию. Например, часто используемые инструментальные методы map, reduce и sort являются функциями более высокого порядка. Компонент более высокого порядка, аналогичный функции более высокого порядка, принимает компонент React в качестве входных данных и выводит новый компонент React. Существует два способа реализации компонентов более высокого порядка:

  • Прокси свойств (props proxy). Компоненты более высокого порядка манипулируют реквизитами через обернутый компонент React.
  • Инверсия наследования. Компоненты более высокого порядка наследуются от обернутых компонентов React.

Причина определения ключа из рекомендованного компонента реакции.

Алгоритмическое усовершенствование и оптимизация diff как ускорителя Virtual DOM являются основой и гарантией производительности всего рендеринга интерфейса React, а также самой загадочной и невероятной частью исходного кода React. Этот раздел по-прежнему начинается с исходного кода и подробно анализирует невероятные вещи, связанные с diff.

Вот 3 стратегии для алгоритма React diff

  • Стратегия 1: межуровневое перемещение узлов DOM в веб-интерфейсе очень мало и может быть проигнорировано.
  • Стратегия 2: Два компонента с одним и тем же классом будут генерировать похожие древовидные структуры, а два компонента с разными классами будут генерировать разные древовидные структуры.
  • Стратегия 3: группу дочерних узлов на одном уровне можно отличить по уникальным идентификаторам.

Третья стратегия: элемент diff.Когда узлы находятся на одном уровне, diff обеспечивает 3 вида операций с узлами, а именно INSERT_MARKUP (вставка), MOVE_EXISTING (перемещение) и REMOVE_NODE (удаление).

Например, старый набор содержит узлы A, B, C и D, а обновленный новый набор содержит узлы B, A, D и C. В это время новый и старый наборы сравниваются с помощью diff, и это нашли, что B != A, затем создайте И вставьте B в новый набор, удалите старый набор A и так далее, создайте и вставьте A, D и C, удалите B, C и D.

WechatIMG4.jpeg-53.3kB

Для некоторых узлов одинаковых, но из-за смены положения требуются сложные и неэффективные операции удаления и создания, по сути нужно только переместить положения этих узлов. React предлагает стратегию оптимизации: он позволяет разработчикам добавлять уникальные ключи для различения одной и той же группы дочерних узлов на одном уровне.Хотя это лишь небольшое изменение, производительность претерпела потрясающие изменения!

Узлы, содержащиеся в старом и новом наборах, показаны на рисунке.После сравнения разницы различий обнаруживается, что узлы в старом и новом наборах являются одними и теми же узлами по ключу, поэтому нет необходимости удалять и создавать узлы, и нужно только изменить положение узлов в старом наборе. Переместите и обновите его до положения узла в новом наборе. В это время результат сравнения, выдаваемый React, таков: B и D не выполнять любую операцию, а A и C могут выполнять операцию перемещения.

WechatIMG5.jpeg-71.1kB

redux

объединить редукторы в редуксе

Роль вспомогательной функции combReducers состоит в том, чтобы объединить объект с несколькими различными функциями редуктора в качестве значения в конечную функцию редуктора, а затем вы можете вызвать createStore для этого редуктора.

Комбинированный редьюсер может вызывать отдельные дочерние редюсеры и объединять их результаты в единый объект состояния. Структура объекта состояния определяется ключами нескольких переданных редюсеров.

В конечном итоге структура объекта состояния будет выглядеть так:

{
  reducer1: ...
  reducer2: ...
}

Управляйте именованием ключа состояния, называя редюсер входящего объекта по-разному. Например, вы можете вызвать combReducers({ todos: myTodosReducer, counter: myCounterReducer }), чтобы изменить структуру состояния на { todos, counter }.

Общепринятой практикой является именование редюсеров, а затем указание на разделение этой информации, поэтому вы можете использовать сокращение ES6: combReducers({ counter, todos }) . Это то же самое, что и combReducers({ counter: counter, todos: todos }) .

Инструкции для пользователей Flux Эта функция может помочь вам организовать несколько редьюсеров для управления их собственным связанным состоянием. Подобно Flux, несколько хранилищ управляют разными состояниями. В Redux есть только одно хранилище, но CombineReducers позволяет вам иметь несколько редюсеров, сохраняя при этом независимость соответствующих логических блоков.

  • параметр редукторы (объект): объект, значение которого соответствует различным функциям редукторов, которые позже будут объединены в одну. Далее будут представлены правила, которым должна соответствовать функция входящего редуктора.

  • возвращаемое значение (Функция): вызов редукторы все объекты в редукторе редуктора, и построят структуру объекта и редукторы одинаковых объектов состояния.

Уведомление Эта функция немного субъективна, когда она разработана, просто чтобы избежать некоторых распространенных ошибок, допускаемых новичками. Из-за этого мы намеренно установили некоторые правила, но если вы вручную пишете корневой редуктор, вам не нужно следовать этим правилам.

Каждый редьюсер, переданный в combReducers, должен удовлетворять следующим правилам:

Все несопоставленные действия должны возвращать первый полученный параметр, то есть состояние.

никогда не может возвращать значение undefined. Очень легко сделать эту ошибку при преждевременном возврате.Чтобы избежать распространения ошибки, combReducers в этом случае выдаст исключение.

Если входящее состояние не определено, обязательно верните начальное состояние соответствующего редуктора. Согласно предыдущему правилу, undefined запрещено для начального состояния. Легко установить начальное состояние, используя синтаксис значения параметра ES6 по умолчанию, но вы также можете вручную проверить, не определен ли первый параметр.

Хотя combReducers автоматически проверяет, соответствует ли ваш редьюсер указанным выше правилам, вы также должны помнить и стараться следовать им.

//模拟一个combineReducers
var combineReducers1 = function(obj){
    //内部具体代码

    var finalState = {};
    function reducer(state,action){
        //reducer具体逻辑

        for (var p in obj) {
         //根据key属性值调用function(state.属性名,action)
         finalState[p] = obj[p](state[p], action);
        }

        //返回state
        return finalState;
    }

    //返回最终的reducer
    return reducer;
}

Понимание промежуточного ПО Redux

Перед лицом различных бизнес-сценариев, очевидно, не универсально просто модифицировать код диспетчера или редуктора. Нам нужен механизм плагинов, который можно комбинировать и свободно подключать. Redux использует Koa (который используется для сборки Web Идея промежуточного ПО в рамках Node.js приложения).

Редуктор в Redux больше связан с логикой преобразования данных, поэтому промежуточное ПО улучшает диспетчеризацию.

WechatIMG6.jpeg-69.6kB

Вот исходный код реализации промежуточного программного обеспечения

export default function applyMiddleware(...middlewares) {
    return (next) => (reducer, initialState) => {
        let store = next(reducer, initialState);
        let dispatch = store.dispatch;
        let chain = [];
        var middlewareAPI = {
            getState: store.getState,
            dispatch: (action) => dispatch(action),
        };    
        chain = middlewares.map(middleware => middleware(middlewareAPI));
        dispatch = compose(...chain)(store.dispatch);
    return {
        ...store,
        dispatch,
        };
    }
}

Исходники разбирать не буду.Я читал этот исходник минимум 5 раз,но так толком и не понял.Суть понять сложно.

WechatIMG7.jpeg-39.2kB


пасхальные яйца

Разница между веб-пакетом и глотком

Принцип упаковки webpack: 1. Все представляет собой модуль. Учитывая основной файл (например, index.js), затем начните с этого основного js, чтобы набрать все зависимые js, css, img и т. д. через загрузчик, чтобы проанализировать их в выводе модуля.

В чем разница с gulp.

Поскольку использовался gulp, его конфигурация任务,列task, такие как сжатие js, парсинг. Подобно компиляции, комбинированию и сжатию изображений less или sass, gulp — это инструмент, обеспечивающий процесс. Вы также можете выполнить gulp для настройки процесса перед webpack, а затем использовать gulp для запуска webpack~

Внедрить несколько плагинов webpack

  • copy-webpack-plugin: скопировать один или весь каталог в каталог сборки
  • Экстракт-текстовый веб-плагин: отделите текст при упаковке, и упаковывайте его в отдельный файл

Те проблемы, возникающие на работе? Как решить.

Этот вопрос в основном 100% должен быть задан. Я думаю, что могу найти вопрос в своем собственном проекте, который свеж в моей памяти, но также подчеркивает трудности и справляется с ними. Он слишком прост и не может подчеркнуть вашу силу. Интервьюер кто освоил это, будет разоблачено, как только он копает глубоко, хахахаха

Большое спасибо автору «Углубленного стека технологий React»: Чен Йи. Эта книга действительно многому меня научила на пути реагирования ~рекомендуется~

Ссылки:

Опыт фронтенд-интервью в июне 2018 года (часть 1)

Опыт фронтенд-интервью в июне 2018 года (посередине)