Метод componentWillReceiveProps больше не запускается при использовании сокращения для вызова api

Я собираюсь вызвать api с помощью redux: я использовал axios, history, react-redux, react-redux react-router-native, react-router, redux-promise-middleware, redux-thunk чтобы сделать api-вызов с помощью redux: я сделал Reducers и поместите весь мой файл редуктора в свой собственный файл и объедините их в основной файл, как это, это мой файл generateoptReducer.js:

const initialState = {
    data: {},
    error: null,
    status: null
};
import {generateOTP} from '../Actions/api';
export default function reducer(state = initialState, action) {

    switch (action.type) {
        case (action.type === 'GENERATEOTP_PENDING' || {}).input:
            // Action is pending (request is in progress)
            return {...state, status: 'fetching',methodes:'done1'};
        case (action.type === 'GENERATEOTP_FULFILLED' || {}).input:
            // Action is fulfilled (request is successful/promise resolved)
            return {
                ...state,
                error: null,
                data: action.payload.data,
                status: 'success',
                methodes:'done1'
            };
            case 'generateOTP':
                // Action is fulfilled (request is successful/promise resolved)
                return {
                    ...state,
                    error: null,
                    data: action.payload.data,
                    status: 'success',
                    methodes:'done1'
                };
        case (action.type === 'GENERATEOTP_REJECTED' || {}).input:
            // Action is rejected (request failed/promise rejected)
            return {
                ...state,
                error: action.payload,
                status: 'error'
            };
        default:
            return state;
    }
};

И объедините их в файле index.js:

import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';

//import api from './api-reducer';


import generateotp from './generateotpReducer';
import login from './loginReducer';

export default combineReducers({
  generateotp,
  login,
  routing: routerReducer,
});

Я также создал другую папку с именем Action и поместил все свои api в файл с именем api.js:

Это мое действие выше редуктора:

export const generateOTP = (phone_number) => ({
    type: 'GENERATEOTP',
    payload: axios({
        method: 'GET',
        url: format(generate_endpoint, phone_number, serviceId),
        headers: {"Accept": "application/json","Content-Type":"application/json"}
    })
});

это тоже мой магазин:

import { applyMiddleware, createStore } from 'redux';
import { routerMiddleware } from 'react-router-redux';
import thunk from 'redux-thunk';
import promiseMiddleware from 'redux-promise-middleware';
import logger from 'redux-logger'
import reducers from './Reducers';

export default function configureStore(history) {
  const middleware = applyMiddleware(
    promiseMiddleware(),
    thunk,

    routerMiddleware(history));
  return createStore(reducers, {}, middleware);
}

и это то, как я отправляю действие: импортированное, как это, в моем файле компонента:

import { generateOTP } from "../Components/Actions/api";

и отправьте действие следующим образом:

this.props.dispatch(generateOTP(formatted_phone_number));

Я также подключаю этот компонент в нижней части файла:

export default connect(state => state)(SignIn)

Теперь мне нужен результат этого api. Я использовал метод componentWillReceiveProps для получения результата. Я не знаю, почему этот компонент не работает. Я искал слишком много, я нахожу путаный результат, в котором говорится, что состояние не меняется, тогда componentWillReceiveProps не запускается !!! хорошо, что api-вызов успешно, и я вижу журнал, и я вижу %cGENERATEOTP_PENDING а затем %cGENERATEOTP_FULFILLED в %cGENERATEOTP_FULFILLED log и api успешно, но проблема %cGENERATEOTP_FULFILLED с componentWillReceiveProps (который больше не работает), который Раньше я получал результат вызова api.

Ответы

Ответ 1

Оператор switch выглядит в формате mailformed

case (action.type === 'GENERATEOTP_FULFILLED' || {}).input:

Это никогда не будет выполняться, потому что (action.type === 'GENERATEOTP_FULFILLED' || {}) будет либо true, либо {}, и ?.input будет всегда undefined

Вам нужно написать smth, чтобы подтвердить некоторые дополнительные параметры:

switch (action.type) {
    case 'GENERATEOTP_PENDING':
        if (action.input) {
            // Action is pending (request is in progress)
            return {...state, status: 'fetching',methodes:'done1'};
        }
        break; //!
    ...
}

Ответ 2

componentWillReceiveProps (nextProps){

console.log('get here',nextProps. fullState)

}

используйте соединение, подобное этому

function mapStateToProps(state) {
console.log('get your state here',state)
  return {
   fullState: state.appState,
  };
}

export default connect(mapStateToProps, {generateOTP})(SignIn);

Ответ 3

Ваш код редуктора выглядит немного. У тебя есть:

switch (action.type) {
  case (action.type === 'GENERATEOTP_PENDING' || {}).input:
      // Action is pending (request is in progress)
      return {...state, status: 'fetching',methodes:'done1'};
  case (action.type === 'GENERATEOTP_FULFILLED' || {}).input:
      // Action is fulfilled (request is successful/promise resolved)
      return {
          ...state,
          error: null,
          data: action.payload.data,
          status: 'success',
          methodes:'done1'
      };
  case 'generateOTP':
      // Action is fulfilled (request is successful/promise resolved)
      return {
          ...state,
          error: null,
          data: action.payload.data,
          status: 'success',
          methodes:'done1'
      };
  // ... etc
}

Оператор switch смотрит на action.type, затем первые два случая пытаются получить доступ (action.type === 'ACTION_NAME' || {}).input. Это утверждение либо решает (a Boolean instance).input, либо {}.input. Каждый из этих случаев будет "ложным", потому что input не является свойством ни в одном из этих значений. Когда код запускается, программа будет сравнивать значение action.type с (false || {}).input action.type, которое никогда не будет истинным, и, таким образом, этот случай не будет запущен.

Я не уверен, что вы пытаетесь вычислить в первых двух случаях, но следующий случай в инструкции switch выглядит более корректно, где у вас просто есть имя действия в виде строки (case 'generateOTP').

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

Ответ 4

Как упоминалось выше, ваш файл "редуктор" выглядит довольно странно.

Шкаф переключения должен быть

switch (action.type) {
  case 'GENERATEOTP_PENDING':
    //stuff
    break;
  case 'GENERATEOTP_FULFILLED':
    //stuff
    break;
  case 'generateOTP':
    //stuff
    break;

но еще одна проблема, которая, как мне кажется, состоит в том, что действие "generateOTP" устанавливает "обещание" внутри действия для reducex.

Редуктор обрабатывает, как обычный объект данных.

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

Ответ 5

Рефакторируйте свое действие, как показано ниже.

export function generateOTP() {
 return {
  type: 'GENERATE_OTP',
  payload:axios({
    method: 'get',
    url: 'http://10.0.2.2:3000/news',
    headers: {"Accept": "application/json"}
  }).then(success => {
    return success
  }).catch(fail => {
    return fail
 })
}

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

Ответ 6

Я предлагаю отправить действие не через this.props.dispatch, а только с отправкой (generateOTP)

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

В моем коде, например:

import * as postActions from '../actions/post'
import * as langActions from '../actions/lang'

const mapDispatchToProps = dispatch => {
  return bindActionCreators(Object.assign({},
     postActions,
     langActions,
  ), dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(News)

Однако, даже если это ваш случай, вы получаете доступ к этому действию не через отправку, а как любые другие функции из ваших реквизитов:

this.props.generateOTP()