Метод 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()