我在显示从数据库(使用 Rails/react/redux)检索的 Pokemon Action 数组时遇到问题。奇怪的是,当我显示整个数组而不尝试使用 join
时,一切都很好。但是,当我尝试对其使用 join
时,收到以下错误消息:Uncaught TypeError: Cannot read property 'join' of undefined
。当我按原样显示整个数组变量而不修改任何内容时,它确实会显示。
我已经检查了我的代码,并确认路由正常并且正在调度正确的操作创建者。我还检查了我的 reducer ,我可以确认它们正在使用正确的操作常量来决定新的状态对象是什么。我唯一能想到的是,问题可能出在以下这些地方之一:
//将我的 Pokemon 详细信息呈现到页面上的组件
class PokemonDetail extends React.Component {
componentDidMount() {
this.props.requestSinglePokemon(this.props.match.params.pokemonId);
}
componentDidUpdate(prevProps) {
if (prevProps.match.params.pokemonId !== this.props.match.params.pokemonId) {
this.props.requestSinglePokemon(this.props.match.params.pokemonId);
}
}
render() {
const { pokemon } = this.props;
if (!pokemon) return null;
return (
<section className='pokemon-detail'>
<figure>
<img src={ pokemon.image_url } alt={ pokemon.name } />
</figure>
<ul>
<li><h1>{ pokemon.name }</h1></li>
<li>Type: { pokemon.poke_type }</li>
<li>Attack: { pokemon.attack }</li>
<li>Defense: { pokemon.defense }</li>
<li>Moves: { pokemon.moves.join(', ') }</li>
</ul>
</section>
);
}
}
// reducer
const pokemonReducer = (state = {}, action) => {
Object.freeze(state);
let poke;
switch(action.type) {
case RECEIVE_ALL_POKEMON:
return Object.assign({}, state, action.pokemon);
case RECEIVE_SINGLE_POKEMON:
poke = action.payload.pokemon;
return Object.assign({}, state, { [poke.id]: poke });
default:
return state;
}
}
// Action 创建者
export const requestSinglePokemon = id => dispatch => {
dispatch(startLoadingSinglePokemon());
return APIUtil.fetchSinglePokemon(id).then(pokemon => dispatch(receiveSinglePokemon(pokemon)));
}
export const receiveSinglePokemon = payload => ({
type: RECEIVE_SINGLE_POKEMON,
payload
});
//后端APIUtil方法
export const fetchSinglePokemon = id => (
$.ajax({
method: 'GET',
url: `api/pokemon/${id}`
})
);
这是最奇怪的事情......当我执行 { JSON.stringify(pokemon.moves) }
时,我可以从字面上看到它是一个字符串数组(Pokemon Action )。即使我只是像这样显示它, { pokemon.moves }
,它似乎正确地捕获了正确的 Pokemon;名称、类型、攻击和防御文本都在那里,并且还显示了 Action (尽管格式不正确)。
注意:在观察我的日志时(它向我显示了当我与页面交互时调度的操作创建者),join
的错误似乎在应该已分派(dispatch)的操作创建者(即我发现在弹出此错误之前从未分派(dispatch) START_LOADING_SINGLE_POKEMON
操作)
最佳答案
对于应用程序的第一次渲染,尚未调度任何操作。 componentDidMount 在初始渲染后发生。 因此,除非“PokemonDetail”的父组件传递一个带有键“moves”的初始神奇宝贝对象,其值为数组类型,否则第一次渲染时会导致此错误。
您可以基于“Pokemon”对象在“PokemonDetail”组件内进行条件渲染,或者让“pokemon”的初始状态包含 reducer 中的移动数组。
关于javascript - 当我尝试在组件上使用数组方法时,为什么组件中的数组变量未定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59870901/