【问题标题】:componentWillReceiveProps method doesn't run anymore when using redux to call api使用redux调用api时componentWillReceiveProps方法不再运行
【发布时间】:2018-05-08 19:52:29
【问题描述】:

我将使用redux 调用api: 我使用axios,history,react-redux,react-router-native,react-router,,redux-promise-middleware,redux-thunk组件使用redux进行api调用: 我创建了Reducers 文件夹并将我所有的reducer 文件放在他们自己的文件中,并将它们组合到这样的主文件中 这是我的 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,api调用成功但问题出在componentWillReceiveProps(没有运行更多),我曾经接收过 api 调用的结果。

【问题讨论】:

  • 对不起,如果我的问题很愚蠢,您将实际部署哪个文件componentWillReceiveProps,提供足够的信息总是好的,但是这个很难追踪。也许您可以重新组织它以帮助想要伸出援助之手的人。
  • 你使用过Provider吗,你是如何创建商店的,你在哪里有componentWillReceiveProps
  • @ShubhamKhatri 感谢您的回复,我在这条路径上分享了我的整个项目github.com/Husseinoj/reactapi
  • @Carr 谢谢,我在我的 github 上分享了这个项目,当我只调用一个 api 时项目运行良好
  • 我检查了项目,componentWillReceiveProps 正在被调用,但我无法解析 api,因为它可能指向您的服务器。

标签: javascript reactjs react-native react-redux react-router-redux


【解决方案1】:

我建议不通过 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()

【讨论】:

    【解决方案2】:

    按照以下重构您的操作。

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

    根据上述cmets,减速器必须固定。

    【讨论】:

      【解决方案3】:

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

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

      这永远不会运行,因为(action.type === 'GENERATEOTP_FULFILLED' || {}) 将是true{},而?.input 将始终是undefined

      你需要这样写来验证一些额外的参数:

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

      【讨论】:

        【解决方案4】:

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

        开关盒应该是

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

        但我认为我们遇到的另一个问题是“生成 OTP”的操作 正在将动作中的“承诺”设置为 redux。

        reducer 像处理普通数据对象一样处理它。

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

        【讨论】:

        • 他正在使用 redux-promise-middleware 来处理有效载荷中的承诺。当 promise 被解决时,redux-proimise-middleware 会相应地发送操作。并且减速器应该始终没有副作用。所以在我看来,在减速器中处理你的 peomise 是一种反模式
        • 我不在减速器中处理它:) 我只是说他应该在动作中处理,但如果他真的想要,他可以在减速器中这样做。我使用 redux saga 和 thunk
        【解决方案5】:

        你的 reducer 代码看起来有点不对劲。你有:

        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 代码永远不会运行,即使网络请求运行。

        【讨论】:

          【解决方案6】:
          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);
          

          【讨论】:

          • 但我将状态映射到了这样的道具 export default connect(state => state)(SignIn)
          猜你喜欢
          • 2018-07-19
          • 1970-01-01
          • 1970-01-01
          • 2018-06-08
          • 1970-01-01
          • 2016-08-27
          • 2018-02-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多