React Redux - Normalizr - 从嵌套数据中选择 - select by id
React Redux - Normalizr - Selecting from nested data - select by id
这个问题有点卡住了。我收到了一份针对艺术作品列表的回复,这是一个深度嵌套的回复。我已经使用 normalizr 库规范了这个响应。
您可以查看以下架构:
../schema.js
import { Schema, arrayOf } from 'normalizr'
const artboardSchema = new Schema('artboards', { idAttribute: 'id' });
const artistSchema = new Schema('artists', { idAttribute: 'id' });
const lastArtSchema = new Schema('lastArt', { idAttribute: 'id' });
const artSchema = new Schema('art', { idAttribute: 'id' });
const artAssetSet = new Schema('artAssetSet', { idAttribute: 'url'});
artboardSchema.define({
collaborated_by: arrayOf(artistSchema),
last_art: lastArtSchema,
art: arrayOf(artSchema)
});
artSchema.define({
artasset_set: arrayOf(artAssetSet),
performed_by: artistSchema
});
lastArtSchema.define({
performed_by: artistSchema
});
export { artboardSchema }
到目前为止效果很好,数据正在规范化,我在状态树中保存了以下响应:
artboard:
entities:
artboards {}
artists {}
lastArt {}
art {}
artAssetSet {}
result:
[2,3,4,5,6]
所以现在我有一个组件可以获取这些数据并显示它。
../ArtCard.jsx
const ArtCard = (props) => {
return (
<div className={props.cardContainer}>
{props.item.result.map( id =>
<div className={props.itemClass} value={id} key={id}>
<h5>{props.item.entities.artboards[id].name}</h5>
<p>{props.item.entities.artboards[id].uid}</p>
{props.item.entities.artboards[id].collaborated_by.map( id =>
<Avatar key={id} name={props.item.entities.artists[id].name} size={40} round={true}/>
)}
<button className="btn btn-primary" style={{cursor: 'pointer'}} onClick={() => {
props.onSubmit()
}
}>Details</button>
</div>
)}
</div>
);
};
上面的组件从状态树中获取了整个画板对象,然后我们在其上运行.map,通过id获取画板。
我遇到的问题是关于 last_art,我想显示最后一幅画的艺术家,我可以通过放置 {props.item.entities.artboards[id].last_art}
来获取 ID,但是我在使用它从 lastArt 获取信息时遇到问题,即这类似于 {props.item.entities.lastArt[id].date}
或 {props.item.entities.lastArt[id].artist}
,因为 last_art 不是数组,而只是 Number
,这意味着我不能在上面使用 map
。
有更好的方法吗?在这种情况下我错过了什么?
所以我能够解决这个问题,这实际上是一个相当简单的解决方案。我不得不考虑 last_art id 也为空。
const PatientCard = (props) => {
return (
<div className={props.cardContainer}>
{props.item.result.map( id =>
<div className={props.itemClass} value={id} key={id}>
<h5>{props.item.entities.artboards[id].name}</h5>
<span className={props.lastArtClass}>
{props.item.entities.artboards[id].last_art !== null &&
<span>
<span>{props.item.entities.artists[props.item.entities.lastArt[props.item.entities.artboards[id].last_art].performed_by].name}, </span>
<FormattedRelative value={props.item.entities.lastArt[props.item.entities.artboards[id].last_art].date} />
</span>
}
{props.item.entities.artboards[id].last_art === null &&
<p>N/A</p>
}
</span>
{props.item.entities.artboards[id].collaborated_by.map( id =>
<Avatar key={id} name={props.item.entities.artists[id].name} size={40} round={true}/>
)}
<button className="btn btn-primary" style={{cursor: 'pointer'}} onClick={() => {
props.onSubmit()
}
}>Details</button>
</div>
)}
</div>
);
};
我认为使用 Reselect 绝对是更好的方法。
这个问题有点卡住了。我收到了一份针对艺术作品列表的回复,这是一个深度嵌套的回复。我已经使用 normalizr 库规范了这个响应。
您可以查看以下架构:
../schema.js
import { Schema, arrayOf } from 'normalizr'
const artboardSchema = new Schema('artboards', { idAttribute: 'id' });
const artistSchema = new Schema('artists', { idAttribute: 'id' });
const lastArtSchema = new Schema('lastArt', { idAttribute: 'id' });
const artSchema = new Schema('art', { idAttribute: 'id' });
const artAssetSet = new Schema('artAssetSet', { idAttribute: 'url'});
artboardSchema.define({
collaborated_by: arrayOf(artistSchema),
last_art: lastArtSchema,
art: arrayOf(artSchema)
});
artSchema.define({
artasset_set: arrayOf(artAssetSet),
performed_by: artistSchema
});
lastArtSchema.define({
performed_by: artistSchema
});
export { artboardSchema }
到目前为止效果很好,数据正在规范化,我在状态树中保存了以下响应:
artboard:
entities:
artboards {}
artists {}
lastArt {}
art {}
artAssetSet {}
result:
[2,3,4,5,6]
所以现在我有一个组件可以获取这些数据并显示它。
../ArtCard.jsx
const ArtCard = (props) => {
return (
<div className={props.cardContainer}>
{props.item.result.map( id =>
<div className={props.itemClass} value={id} key={id}>
<h5>{props.item.entities.artboards[id].name}</h5>
<p>{props.item.entities.artboards[id].uid}</p>
{props.item.entities.artboards[id].collaborated_by.map( id =>
<Avatar key={id} name={props.item.entities.artists[id].name} size={40} round={true}/>
)}
<button className="btn btn-primary" style={{cursor: 'pointer'}} onClick={() => {
props.onSubmit()
}
}>Details</button>
</div>
)}
</div>
);
};
上面的组件从状态树中获取了整个画板对象,然后我们在其上运行.map,通过id获取画板。
我遇到的问题是关于 last_art,我想显示最后一幅画的艺术家,我可以通过放置 {props.item.entities.artboards[id].last_art}
来获取 ID,但是我在使用它从 lastArt 获取信息时遇到问题,即这类似于 {props.item.entities.lastArt[id].date}
或 {props.item.entities.lastArt[id].artist}
,因为 last_art 不是数组,而只是 Number
,这意味着我不能在上面使用 map
。
有更好的方法吗?在这种情况下我错过了什么?
所以我能够解决这个问题,这实际上是一个相当简单的解决方案。我不得不考虑 last_art id 也为空。
const PatientCard = (props) => {
return (
<div className={props.cardContainer}>
{props.item.result.map( id =>
<div className={props.itemClass} value={id} key={id}>
<h5>{props.item.entities.artboards[id].name}</h5>
<span className={props.lastArtClass}>
{props.item.entities.artboards[id].last_art !== null &&
<span>
<span>{props.item.entities.artists[props.item.entities.lastArt[props.item.entities.artboards[id].last_art].performed_by].name}, </span>
<FormattedRelative value={props.item.entities.lastArt[props.item.entities.artboards[id].last_art].date} />
</span>
}
{props.item.entities.artboards[id].last_art === null &&
<p>N/A</p>
}
</span>
{props.item.entities.artboards[id].collaborated_by.map( id =>
<Avatar key={id} name={props.item.entities.artists[id].name} size={40} round={true}/>
)}
<button className="btn btn-primary" style={{cursor: 'pointer'}} onClick={() => {
props.onSubmit()
}
}>Details</button>
</div>
)}
</div>
);
};
我认为使用 Reselect 绝对是更好的方法。