Функция подключения React-redux не может сопоставлять состояние с реквизитами после нескольких последовательных изменений состояния с использованием redux-saga

У меня есть простой редуктор:

// reducer.js
const itemId = (state = "", action) => {
  if (action.type === SET_ID) {
    console.log("reducer updated");
    return action.payload.id;
  }
  else {
    return state;
  }
};

Компонент, подключенный к магазину:

const Component = ({ itemId }) => {
  console.log("Component rendered");
  return <div> {itemId}</div>;
};

const mapStateToProps = state => ({
  itemId: state.itemId
});

export const ConnectedComponent = connect(mapStateToProps)(Component);

И сага с тремя действиями, где у первого и последнего действия одинаковая полезная нагрузка:

const createSetIdAction = id => ({
  type: SET_ID,
  payload: {
    id
  }
});

export const saga = function*() {
  yield put(createSetIdAction("FirstID"));
  yield put(createSetIdAction("SecondID"));
  yield put(createSetIdAction("FirstID"));
};

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

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

Когда я добавляю небольшую задержку (более примерно 35 мс в моем браузере), все начинает работать:

// saga
  yield put(createSetIdAction("First_ID"));
  yield delay(35);
  yield put(createSetIdAction("Second_ID"));
  yield put(createSetIdAction("First_ID"));

и компонент отображается так, как ожидалось.

Есть ли способ заставить функцию подключения отображать компонент после каждого обновления состояния без использования delay в саге?

Рабочая песочница здесь


person mtbno    schedule 26.02.2020    source источник


Ответы (1)


Я сопровождаю Redux.

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

Это связано с комбинацией того, как React-Redux управляет подписками в магазине и распространяет обновления, а также с тем, как React выполняет повторный рендеринг пакетов.

person markerikson    schedule 26.02.2020