Инициализировать состояние перед mapStateToProps? - PullRequest
0 голосов
/ 10 июля 2019

Я знаю, что мой вопрос связан с неправильным пониманием response-redux, но я опишу свой вариант использования, надеясь, что кто-нибудь укажет мне правильное направление.

Я пытаюсь сохранить выбранные ключи строк (selectedRowKeys)из таблицы (муравейник стол) внутри магазина редукса.Все работает, когда структура хранилища проста:

selectedRowKeys: []

Но я хочу сохранить это состояние в нормализованной форме для обработки нескольких таблиц и свойств нескольких таблиц:

tables: {
 123fdfas-234dasf-234asdf-23rfa : { //table id
    id: 123fdfas-234dasf-234asdf-23rfa,
    selectedRowKesy: []
    //... other properities
    }
}

проблема в том, что это состояние не существует, когда приставка пытается mapStateToProps, как это:

const mapStateToProps = (state, ownProps) => {
  if (!ownProps.id) {
    ownProps.id = uuidv4();
  }

  return {
    selectedRowKeys: state.tables[ownProps.id].selectRowKeys
  };
};

state.tables[ownProps.id] не определено, поэтому есть ошибка.

Я подумал, что мне нужнокак-то инициализировать состояние, но это привело меня к еще большему замешательству.Что я понял до сих пор:

  • Я не могу инициализировать состояние в редукторе, как reducerName (state = initialState, action), потому что действие не отправлено, и нет action.id (объект действия имеет полезную нагрузку с идентификатором таблицы).
  • Я не могу отправить действие INIT_TABLE в componentDidMount(), потому что mapStateToProps выполняется первым, поэтому state.tables[ownProps.id] все еще не определено.

Мне кажется, что этот вариант использованиястранно, и поэтому я не могу найти решение, хотя я гуглю и думаю об этом в течение 3 дней.

Пожалуйста, ведите меня, я нахожусь в сумасшедшем цикле :)

Этомой первый ТАК вопрос, пожалуйста, дайте мне знать, если что-то неясно.

Ответы [ 2 ]

1 голос
/ 10 июля 2019

Кто отвечает за создание новой таблицы?Это решающий фактор, как решить эту проблему.

Идентификатор определенно не должен быть создан в mapStateToProps, и вы не должны мутировать ownProps.Я удивлен, если это даже работает.Идентификатор должен быть создан в действии, если используется приставка.

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

Независимо от того, какую опцию вы выберете, вашmapStateToProps должен корректно обрабатывать пустое состояние, т.е.selectedRowKeys должно быть установлено на какое-то значение по умолчанию, если оно отсутствует (возможно, пустой массив или ноль?).И ваш компонент должен обрабатывать пропущенные значения, если нет доступного нормального значения по умолчанию.Обычно в функции рендеринга есть несколько нулевых проверок, которые возвращают null до тех пор, пока данные не станут доступны.

0 голосов
/ 10 июля 2019

Из моего понимания проблемы вы слишком конкретны!

В этом случае это не очень хорошая практика.Я советую следующее.

Предположим, что у вас есть редуктор tables:

const mapStateToProps = ({ tables }, ownProps) => {
  return {
    tables,
  };
};

Это позволит сделать редукторы tables доступными в this.props

* 1012 вашего компонента* Таким образом, вы можете выполнить следующие действия в любом месте компонента, чтобы получить выбранные строки, определить этот метод и использовать его в правильном месте вместо непосредственного выполнения этого в mapStateToProps, что не является хорошей практикой.
getSelectedRowKeys = (ownProps) => {
  if (!ownProps.id) {
    ownProps.id = uuidv4();
  }
  const selectedRowKeys = [];
  const table = this.props.tables[ownProps.id];
  const selectedRowKeys = table && table.selectRowKeys; //if table exists get the row keys.

  return selectedRowKeys || []; //if selectedRowKeys are not there return an empty array.
}
...