我正在创建一个用于学习目的的react / redux应用程序。我试图通过他们的api从满足中提取图像。我已经设置了一个动作,缩减器和组件,可以很好地显示图像,但是当在页面之间导航时,图像是重复的。每当我返回同一页面时,图像重复+ 1,所以如果我访问该页面五次,该图像将在该页面上存在5次。
如果有人能给我一些关于如何调试这个甚至解决问题的指示,那将是很棒的。
动作
export function fetchAsset(id) {
const request = axios.get(`${API_BASE_URL}/spaces/${API_SPACE_ID}/assets/${id}?access_token=${API_TOKEN}`);
return {
type: FETCH_ASSET,
payload: request
};
}
减速器
import { FETCH_ASSET } from '../actions/index';
const EMPTY_ARRAY = []
export default function(state = EMPTY_ARRAY, action) {
switch(action.type) {
case FETCH_ASSET:
return [ ...state, action.payload.data];
default:
return state;
}
}
资产组件
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchAsset } from '../actions/index';
import styled, { css } from 'styled-components';
const RespImg = styled.img`
width: 100%;
`
class Asset extends Component {
componentWillMount() {
this.props.fetchAsset(this.props.assetId)
}
shouldComponentUpdate(nextProps, nextState) {
return true;
}
renderAsset() {
var assetArray = this.props.assets;
console.log(assetArray + ' this.props')
return assetArray.map((asset, index) => {
if (asset.sys.id == this.props.assetId) {
return (
<RespImg src={asset.fields.file.url} alt={asset.fields.file.fileName} key={index}/>
);
}
});
}
render() {
return (
<div className="asset">
{this.renderAsset()}
</div>
);
}
}
function mapStateToProps(state) {
return {
assets: state.assets
};
}
export default connect(mapStateToProps, { fetchAsset })(Asset)
将组件添加到页面
<Asset assetId={work.fields.featuredImage.sys.id} assetKey={index} />
答案 0 :(得分:1)
我认为这里的问题是你多次获取这个图像,这就是为什么它在第一次渲染时都很好。
您将图像保存在阵列中,也许您下载相同的资源,并将其添加到阵列中,即使它已经存在。对于此类实体,可以使用名为normalizing的技术,因此您的状态将如下所示:
state = {
[id]: Asset
};
使用这种技术,您可以通过id获取所需的资产(您可能从URL参数获得)。 Reducer中的数组通常用于集合 - 例如,如果要获取所有资源。你可以规范化响应,并在一个reducer中按id保存实体,在另一个reducer中保存集合请求的结果 - 所以你将拥有一个带有id的数组,以及一个包含所有可能的Assets的对象。
还有一件事 - @Dyo建议您将某些内容放入key
,例如id
或url
,这是一个很好的建议。但是,如果您打开控制台,您可能会看到elements with the same key
的内容。反应基本上,react不会使用相同的键呈现元素,因此可能会渲染相同实体的数组,但只会呈现一个 - 所有其他实体都被丢弃。