Понимание React Redux Reducer и MapstateToProps - PullRequest
0 голосов
/ 14 января 2019

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

  • Почему вариант 2 ниже не работает?
  • Почему я должен сопоставить свое состояние со своей реквизитой CompetitionList, используя state.competitions, а не state.items?
  • Любые ресурсы, чтобы получить представление о том, как работают реагирующие и редукционные функции подключения и отображения. Я уже просмотрел официальные документы и провел поиск в Google, но, возможно, у кого-то есть ссылка, которая показалась ему более понятной для всех различных вариантов и способов отображения состояния и отправки.

Код моего действия:

function getAll() {
    return dispatch => {
        dispatch(request());

        myService.getAll()
            .then(
                competitions => dispatch(success(competitions)),
                error => dispatch(failure(error))
            );
    };

    function request() { return { type: constants.GETALL_REQUEST } }
    function success(competitions) { return {type: constants.GETALL_SUCCESS, competitions}}
    function failure(error) { return {type: constants.GETALL_FAILURE, error}} 
}

Мой код редуктора:

import { constants } from '../_constants';

const initialState = {items: [], loading: false, selected: null}

export function competitions(state = initialState, action) {
  switch (action.type) {
    case constants.GETALL_REQUEST:
      return {
        loading: true
      };
    case constants.GETALL_SUCCESS:
          console.log("the action value: ", action)
      return {
        items: action.competitions
      };
    case constants.GETALL_FAILURE:
          console.log("the failed action value: ", action)
      return { 
        error: action.error
      };
    default:
      return state
  }
}

В моем компоненте у меня есть функция mapStateToProp, которую я передаю для подключения. Первый не работает. Почему?

Вариант 1 - не работает

function mapStateToProps(state) {
    const { selected, ...competitions } = state.competitions;

    return {
        competitionList: competitions,
        isLoading: state.loading
    };
}

export default connect(mapStateToProps)(Dashboard);

Это работает, но я бы хотел, чтобы переменная CompetitionList содержал массив возвращаемых элементов вместо всего объекта состояния, поэтому я попытался сделать что-то подобное competition: state.competitions.items, но возникает ошибка.

Вариант 2 - Частично работает (я хочу назначить только элементы соревнования)

const mapStateToProps = (state) => ({
    competitionList: state.competitions,
    isLoading: state.loading
});


export default connect(mapStateToProps)(Dashboard);

Я не могу сделать:

const { competitionList } = this.props;

{competitionList.map(competition =>
     <tr key={competition.competitionId}>
        <td>{competition.competitionName}</td>
     </tr>
 )}

Мне нужно сделать:

const { competitionList } = this.props;

{competitionList.items.map(competition =>
     <tr key={competition.competitionId}>
        <td>{competition.competitionName}</td>
     </tr>
 )}

1 Ответ

0 голосов
/ 14 января 2019

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

В файле, в котором вы комбинируете свои редукторы, у вас, вероятно, есть что-то вроде этого:

import { combineReducers } from 'redux'
import todos from './todos'
import competitions from './competitions'

export default combineReducers({
  todos,
  competitions
})

После этого ваше состояние будет выглядеть так:

{
  todos:{},
  competitions:{
    items: [],
    loading: false,
    selected: null
  }

}

Объяснил, что, думаю, все будет проще.

Вариант 1 - не работает : он не работает, поскольку у вас нет атрибута competitions в состоянии competitions. Даже если у вас есть, вы не должны использовать ... перед ним. Если вы замените competitions на items, он будет работать, потому что items находится в состоянии competitions:

function mapStateToProps(state) {
    const { selected, items } = state.competitions;

    return {
        competitionList: items,
        isLoading: state.loading
    };
}

export default connect(mapStateToProps)(Dashboard);

Или мы можем улучшить его, чтобы сделать его короче:

function mapStateToProps(state) {
    const { selected, items } = state.competitions;

    return {
        items,
        selected
        isLoading: state.loading
    };
}

export default connect(mapStateToProps)(Dashboard);

Таким образом, вы можете использовать эту часть вашего кода:

const { items } = this.props;

{items.map(competition =>
   <tr key={competition.competitionId}>
      <td>{competition.competitionName}</td>
   </tr>
 )}

Есть еще один момент, на который я хотел бы обратить внимание: возможно, ваша переменная isLoading тоже не работает, потому что вы пытаетесь прочитать ее непосредственно из состояния, а не из редуктора в состоянии.

Отредактировано: Я пропустил еще один момент. Ваш редуктор всегда должен возвращать все состояние, а не только его атрибут.

import { constants } from '../_constants';

const initialState = {items: [], loading: false, selected: null, error: null}

export function competitions(state = initialState, action) {
  switch (action.type) {
case constants.GETALL_REQUEST:
  /*return {
    loading: true
  };*/
  //returning that I will overwrite your competition state with this object.
  

  // this will keep all the competition state and will gerenate a new object changing only the loading attribute
  return {
    ...state,
    loading:true
}
case constants.GETALL_SUCCESS:
      console.log("the action value: ", action)
  return {
    ...state,
    items: action.competitions
  };
case constants.GETALL_FAILURE:
      console.log("the failed action value: ", action)
  return { 
    ...state,
    error: action.error
  };
default:
  return state
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...