componentWillReceiveProps 方法在使用 redux 调用 api 时不再运行



我将使用redux调用 api: 我使用axioshistoryreact-reduxreact-router-nativereact-router、、redux-promise-middlewareredux-thunk组件使用redux进行 api 调用: 我制作了Reducers文件夹,并将我所有的reducer文件放在他们自己的文件中,并将它们合并到一个主文件中,如下所示 这是我生成的选择Reducer.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;
}
};

并将它们合并到索引.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日志和 API 调用,但问题出在我用来接收 API 调用结果的componentWillReceiveProps(不再运行)。

您的 switch 语句看起来是邮件格式的

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; //!
...
}
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);

你的化简器代码看起来有点不对劲。你有:

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进行比较,这永远不会是真的,因此这种情况将不会运行。

我不确定您在前两种情况下尝试计算什么,但是 switch 语句中的下一种情况看起来更正确,您只有一个操作名称作为字符串 (case 'generateOTP')。

我的假设是你的化简器代码永远不会运行,即使网络请求运行。

正如上面的答案提到的,你的"reducer"文件看起来很奇怪。

开关盒应为

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

但我认为我们面临的另一个问题是"生成OTP"的行为 是在操作中设置"承诺"以重新还原。

化简器处理它就像处理普通数据对象一样。

我会处理我行动的承诺 或者至少确保减速器正在处理这一承诺。

按如下方式重构您的操作。

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
})
}

根据上述注释,必须修复减速器。

我建议不要通过this.props.dispatch调度一个动作,而只是通过dispatch(generateOTP)

如果您希望此操作在您的道具中可用,那么在连接方法中,您必须完成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()

相关内容

  • 没有找到相关文章

最新更新