Состояние не определено в mapStateToProps

Я пытался получить новое состояние из моей функции-редуктора VitaminReducer () и подключить его через mapStateToProps. Но когда я console.log состояние, я возвращаюсь "состояние {витамин: undefined}".

Это компонент Vitamins, в котором я вызываю mapStateToProps () (Vitamins.js)

  componentDidMount() {
     this.props.fetchVitamins();
   }

  function mapStateToProps(state) {
     return {
      vitamin: state,
     }
  };

  console.log('the state is', mapStateToProps());

  export default connect(mapStateToProps, { fetchVitamins })(Vitamins);

(redurs.js)

 function vitaminReducer(state = [], action) {
   switch(action.type) {
    case FETCH_VITAMINS_SUCCESS:
      return [
        ...state,
        action.payload.vitamins
      ];
     default:
       return state;
    }
  }


  const reducers = combineReducers({
    vitamin: vitaminReducer,
  });

У меня есть данные, поступающие через экспресс-сервер. Я занес здесь в консоль «витамины» и получаю данные обратно, так что я знаю, что проблема не в этом.

(actions.js)

 export function fetchVitamins() {
   return dispatch => {
     return fetch("/users")
       .then(handleErrors)
       .then(res => res.json())
       .then(micros => {
          dispatch(fetchVitaminsSuccess(micros));
          const vitamins = micros.vitamins;
        }
     )};
  };

  export const FETCH_VITAMINS_SUCCESS = 'FETCH_VITAMINS_SUCCESS';

  export const fetchVitaminsSuccess = vitamins => ({
    type: FETCH_VITAMINS_SUCCESS,
    payload: vitamins
  });

Если я сделаю: «return {Vitamin: state.vitamin,}» вместо «return {Vitamin: state,}», я вернусь «TypeError: Cannot read property 'Vitamin' of undefined». Но это то, что я назвал VitaminReducer в моей функции combReducers () в конце файла redurs.js, так что я подумал, что это правильный способ сделать это.


person John White    schedule 28.05.2018    source источник
comment
вы вызываете mapStateToProps(), но он ожидает состояние в качестве аргумента ... Это функция сопоставления, вы должны просто передать ее connect, а не вызывать ее самостоятельно.   -  person Tomasz Mularczyk    schedule 28.05.2018
comment
@TomaszMularczyk Я немного запутался. Я должен что-то там передать, не так ли? Я хочу передать состояние, чтобы я мог отображать свой массив витаминов с помощью другой функции. Что вы имеете в виду, когда просто передаете это connect, а не вызываете его самостоятельно?   -  person John White    schedule 28.05.2018
comment
@bigjohnjr Вам не нужно вызывать mapStateToProps, потому что это часть внутренних механизмов подключения. Похоже, вы не совсем поняли принципы реакции redux и redux, голова над egghead.io есть хороший учебник от самого Абрамова. Похоже, вы смешиваете ванильный синтаксис JS и ES6 без каких-либо реальных целей, поэтому я настоятельно рекомендую вам пройти курс JS, например, вы не знаете JS. Когда вы вызываете console.log ('the state is', mapStateToProps ());, вы в основном вызываете mapStateToProps с неопределенным аргументом: внутри состояние undefined, что дает вам TypeError.   -  person Loic El Thesea    schedule 28.05.2018
comment
Чего вы пытаетесь достичь? состояние сопоставления свойств должно использоваться (только) connect, таким образом redux-thunk устанавливает свойства компонента в соответствии с store. Итак, какова ваша цель здесь?   -  person Barazu    schedule 28.05.2018
comment
@Barazu, моя цель - просто вернуть массив витаминов в Vitamins.js и использовать мою функцию renderData() для сопоставления каждого витамина и возврата их имен в select раскрывающемся списке   -  person John White    schedule 29.05.2018


Ответы (1)


Спасибо всем за ваш вклад! Я смог заставить его работать.

Я отказался от mapStateToProps () и вместо этого сделал это

(Vitamins.js)

  componentDidMount() {
    this.props.fetchVitamins();
  }

  renderData() {
   const { vitamins } = this.props.vitamins;
    return vitamins.map((micro, index) => {
      return (
        <option value={micro.value} key={index}>{micro.name}</option>
      )
    })
  }

  export default connect(
   state => ({
     vitamins: state.vitamins
   }),
   {
    fetchVitamins
   },
   )(Vitamins);

Я установил действие отправки внутри функции fetchVitamins ()

(actions.js)

  export function fetchVitamins() {
   return dispatch => {
      return fetch("/users")
       .then(handleErrors)
       .then(res => res.json())
       .then(micros => {
         dispatch({
           type: "RECEIVE_VITAMINS",
           payload: micros.vitamins
         });
        }
     )};
   };

   export const RECEIVE_VITAMINS = 'RECEIVE_VITAMINS';

В редукторах я установил initialState для массива vitamins и передал новое состояние micros.vitamins из моего действия RECEIVE_VITAMINS

(redurs.js)

  const initialState = {
    vitamins: [],
  }

 function vitaminReducer(state = initialState, action) {
   switch(action.type) {
     case RECEIVE_VITAMINS:
      return {
        ...state,
        vitamins: action.payload
      };
  default:
     return state;
  }
}


const reducers = combineReducers({
   vitamins: vitaminReducer,
});

Спасибо всем за вашу помощь! Дайте мне знать, если у вас есть другие предложения: D

person John White    schedule 29.05.2018