【问题标题】:Redux state and component property undefined until ajax resolvesRedux 状态和组件属性未定义,直到 ajax 解析
【发布时间】:2016-03-08 21:50:07
【问题描述】:

我的组件通过带有函数的道具获取一些属性:

const mapStateToProps = state => {
  const { entities: { keywords } } = state
  const {locale} = state
  return {
    keywords: keywords[locale]
  }
}

我在同一个组件中使用 ajax 获得了状态关键字:

  componentDidMount() {
    this.props.loadKeywords()
  }

我的组件被渲染了两次。首先,在 ajax 解析之前,所以在我的渲染方法中我得到了 undefined:

render() {
  const { keywords } = this.props.keywords  
  ... 

解决这个问题的正确方法是什么?我将componentDidMount 更改为componentWillMount 没有成功。

现在,基于现实世界的例子,我已经用一个空对象初始化了关键字状态:

function entities(state = { users: {}, repos: {}, keywords: {} }, action) {
  if (action.response && action.response.entities) {
    return merge({}, state, action.response.entities)
  }

  return state
}

我的减速机:

import { combineReducers } from 'redux'
import { routerReducer as router } from 'react-router-redux'
import merge from 'lodash/merge'
import locale from './modules/locale'
import errorMessage from './modules/error'
import searchText from './modules/searchText'

// Updates an entity cache in response to any action with response.entities.
function entities(state = { users: {}, repos: {}, keywords: {} }, action) {
  if (action.response && action.response.entities) {
    return merge({}, state, action.response.entities)
  }

  return state
}

export default combineReducers({
  locale,
  router,
  searchText,
  errorMessage,
  entities
})

我的行动:

import { CALL_API, Schemas } from '../middleware/api'
import isEmpty from 'lodash/isEmpty'

export const KEYWORDS_REQUEST = 'KEYWORDS_REQUEST'
export const KEYWORDS_SUCCESS = 'KEYWORDS_SUCCESS'
export const KEYWORDS_FAILURE = 'KEYWORDS_FAILURE'

// Fetches all keywords for pictos
// Relies on the custom API middleware defined in ../middleware/api.js.
function fetchKeywords() {
  return {
    [CALL_API]: {
      types: [ KEYWORDS_REQUEST, KEYWORDS_SUCCESS, KEYWORDS_FAILURE ],
      endpoint: 'users/56deee9a85cd6a05c58af61a',
      schema: Schemas.KEYWORDS
    }
  }
}

// Fetches all keywords for pictograms from our API unless it is cached.
// Relies on Redux Thunk middleware.
export function loadKeywords() {
  return (dispatch, getState) => {
    const keywords = getState().entities.keywords
    if (!isEmpty(keywords)) {
      return null
    }
    return dispatch(fetchKeywords())
  }
}

全部基于Real world redux example

我的解决方案

给定关键字实体的初始状态。我通过ajax得到这样的json: {'locale': 'en', 'keywords': ['keyword1', 'keyword2']} 但是,当我使用带有 locale 作为 id 的 normalizr 来缓存结果时,我的初始状态就像我在 reducer 中描述的那样:

function entities(state = { users: {}, repos: {}, keywords: { 'en': { 'keywords': [] } } }, action) {
  if (action.response && action.response.entities) {
    return merge({}, state, action.response.entities)
  }

  return state
}

如果我们有多种语言,我不喜欢的是首字母,如果我们添加另一种语言,例如fr,也记得修改它。在这个

keywords: { 'en': { 'keywords': [] } } 

应该是:

keywords: { 'en': { 'keywords': [] }, 'fr': { 'keywords': [] } }

【问题讨论】:

  • 你能发布你的减速器吗?

标签: redux react-redux


【解决方案1】:

这行看起来有问题:

const { keywords } = this.props.keywords

相当于:

var keywords = this.props.keywords.keywords;

我怀疑这就是你的意图。

另一件值得检查的是keywords[locale] 在您的mapStateToProps() 中,它最初可能会解析为未定义。确保你的组件可以处理这个问题,或者给它一个合理的默认值。

【讨论】:

  • 该行是有意的。正如你所建议的,我更新了我的问题,给出了一个合理的默认值。
猜你喜欢
  • 2019-04-07
  • 1970-01-01
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-21
  • 2021-06-27
  • 2018-06-03
相关资源
最近更新 更多