Redux 状态和组件 属性 未定义,直到 ajax 解析
Redux state and component property undefined until ajax resolves
我的组件通过具有以下功能的道具获得一些属性:
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())
}
}
我的解决方案
给定关键字实体的初始状态。我通过 ajax 得到这样的 json:
{'locale': 'en', 'keywords': ['keyword1', 'keyword2']}
但是,当我使用 normalizr 和 locale 作为 id 时,为了缓存结果,我的初始状态就像我在 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': [] } }
这一行看起来有问题:
const { keywords } = this.props.keywords
相当于:
var keywords = this.props.keywords.keywords;
我怀疑这不是你想要的。
另一件值得检查的事情是 mapStateToProps()
中的 keywords[locale]
,它最初可能会解析为未定义。确保您的组件可以处理这个问题,或者给它一个合理的默认值。
我的组件通过具有以下功能的道具获得一些属性:
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())
}
}
我的解决方案
给定关键字实体的初始状态。我通过 ajax 得到这样的 json: {'locale': 'en', 'keywords': ['keyword1', 'keyword2']} 但是,当我使用 normalizr 和 locale 作为 id 时,为了缓存结果,我的初始状态就像我在 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': [] } }
这一行看起来有问题:
const { keywords } = this.props.keywords
相当于:
var keywords = this.props.keywords.keywords;
我怀疑这不是你想要的。
另一件值得检查的事情是 mapStateToProps()
中的 keywords[locale]
,它最初可能会解析为未定义。确保您的组件可以处理这个问题,或者给它一个合理的默认值。