Повторный выбор селектора продолжает пересчет с тем же входом - PullRequest
1 голос
/ 22 октября 2019

Я не понимаю, почему повторный выбор библиотеки пересчитывает селектор с тем же входом. Я проверил FAQ , но он не отвечает на мой вопрос.

Вот пример с реакцией, редукцией, повторным выбором

Codesandbox

import React from "react";
import ReactDOM from "react-dom";
import { createStore } from "redux";
import { Provider, connect } from "react-redux";
import { createSelector } from "reselect";

const initialState = {
  counter: 1
};

const reducer = (state = initialState, action) => {
  if (action.type === "INCREMENT") {
    return { ...state, counter: state.counter + 1 };
  }
  if (action.type === "DECREMENT") {
    return { ...state, counter: state.counter - 1 };
  }
  return state;
};

const store = createStore(reducer);

class ChildComp extends React.Component {
  handleIncrement = () => {
    this.props.increment();
  };

  handleDecrement = () => {
    this.props.decrement();
  };

  render() {
    const { counter, isEven } = this.props;
    return (
      <div>
        <div>counter: {counter}</div>
        <div>is even: {JSON.stringify(isEven)}</div>
        <button onClick={this.handleIncrement}>increment</button>
        <button onClick={this.handleDecrement}>decrement</button>
      </div>
    );
  }
}

const getCounter = state => state.counter;
const isEvenSelector = createSelector(
  getCounter,
  counter => {
    console.log("calculate is even for", counter);
    return counter % 2 === 0;
  }
);

const mapStateToProps = state => {
  return {
    counter: state.counter,
    isEven: isEvenSelector(state)
  };
};

const mapDispatchToProps = dispatch => {
  return {
    increment: () => dispatch({ type: "INCREMENT" }),
    decrement: () => dispatch({ type: "DECREMENT" })
  };
};

const Child = connect(
  mapStateToProps,
  mapDispatchToProps
)(ChildComp);

class App extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <Child />
      </Provider>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Ожидаемое поведение:

начальный (счетчик 1) // вычислить четно для приращения 1
(счетчик 2) // рассчитать четно для уменьшения на 2
(счетчик 1)// не должен console.log, поскольку результат уже вычислен// вычислить четное для 2
декремента (счетчик 1) // вычислить четное для 1

1 Ответ

2 голосов
/ 22 октября 2019

Кэшируется только результат для предыдущего набора входных данных.

В документах говорится:

Селекторы, созданные с помощью createSelector, имеют размер кэша 1Это означает, что они всегда пересчитывают при изменении значения селектора ввода, поскольку селектор сохраняет только предыдущее значение каждого селектора ввода.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...