我的任务是为客户构建一个项目,该项目需要一个包含三个子组件的父组件。具体来说,父组件按照如下方式渲染子组件:
父 = 顶部 + 中间 + 底部
PARENT 组件代表一组项目中的一个。
在 TOP 组件中有一个菜单按钮,显示组中所有项目的列表,目的是如果用户单击这些链接之一,将显示所选项目(PARENT 将“重新呈现”到新项目- PARENT 中的逻辑会导致所选的第二个项目出现,而不是第一个)。
我在这里说得很松散,如果我说的不清楚(我认为应该是),我可以提供代码。
我遇到的主要问题是尝试从子组件之一“重新渲染”父组件。本质上,出现了一个菜单按钮,显示相关项目的列表。单击这些项目之一应重新渲染父组件,但这次显示所选项目。但是,我不知道有什么方法可以做到这一点,希望得到一些建议或帮助。我花了一个上午的时间研究这个话题,并尝试了一些建议的方法,但无济于事。
也许到目前为止我所采用的方法并不是完成此类任务的最佳方法。无论如何,任何帮助都会非常有帮助。谢谢!
编辑:现在工作
编辑 #2:由于这已经获得了很多观点,我只是想澄清一下,这是一个概念证明,也是非常简化的原型/早期版本(没有花哨的翻译等 - 这个想法可以工作吗.. .因为我们当时不确定)。我已经有一段时间没有从事类似的工作了,但我真的很感谢所有帮助我解决我提出的如此令人困惑的问题以及当时什么是一项非常有趣和具有挑战性的任务。
import React from 'react';
import CardHeader from 'components/CardHeader';
import CardContent from 'components/CardContent';
import CardFooter from 'components/CardFooter';
module.exports = React.createClass({
getInitialState: function () {
return {
fullData: '',
//Core Card
userId: '',
cardStack: '',
cardId: '',
//Load Card
loadCard: '1',
//Optional Fields
name: '',
type: '',
headline: '',
subtitle: '',
ctext: '',
imageUrl: '',
price: '',
mapCoordinates: '',
logoUrl: '',
order: '',
email: '',
sponsorUrl: '',
pollId: '',
socialButton: ''
};
}
,
componentWillMount: function () {
//fetches cardStack and card API JSON
/** JSON Structure:
[
cardStack: ...,
cards: ...
]
**/
var fetch = function (userId, cardStackId) {
//AJAX
var json = {
'cardStack': {'id': '1', 'name': 'Test Card Stack', 'userID': 'O1AB0001'},
'cards': [{
'id': '1',
'name': 'Test Card 1',
'cardStack': '1',
'meta': 'meta_note',
'socialButton': 'twitter',
'sponsorUrl': 'https://iwantmyname.com/images/logo-url-shortener-droplr.png',
'order': 1,
'logoUrl': 'https://iwantmyname.com/images/logo-url-shortener-droplr.png',
'product': {
'headline': 'Headline Test',
'subtitle': 'Subtitle Test',
'ctext': 'Hello!!!!',
'imageUrl': 'http://the-mpas.com/wp-content/uploads/2012/04/Image-pic-54-copy.jpg',
'price': '20.00'
}
}, {
'id': '2',
'name': 'Test Card 2',
'cardStack': '1',
'meta': 'meta_note',
'socialButton': 'twitter',
'sponsorUrl': 'https://iwantmyname.com/images/logo-url-shortener-droplr.png',
'order': 2,
'logoUrl': 'https://iwantmyname.com/images/logo-url-shortener-droplr.png',
'product': {
'headline': 'Headline Test 2',
'subtitle': 'Subtitle Test 2',
'ctext': 'Hello 2!!!!',
'imageUrl': 'http://the-mpas.com/wp-content/uploads/2012/04/Image-pic-54-copy.jpg',
'price': '30.00'
}
}]
};
return json;
};
var that = this;
var getCard = function (cardArray, cardOrder) {
var card;
for (var key in cardArray) {
if (cardArray[key].order == cardOrder) {
card = cardArray[key];
}
}
if ('product' in card) {
that.setState({
type: 'product',
headline: card.product.headline,
subtitle: card.product.subtitle,
ctext: card.product.ctext,
imageUrl: card.product.imageUrl,
price: card.product.price
})
}
if ('article' in card) {
that.setState({
type: 'article',
headline: card.article.headline,
ctext: card.article.ctext
})
}
if ('map' in card) {
that.setState({
type: 'map',
mapCoordinates: card.map.mapCoordinates
})
}
if ('relatedvideo' in card) {
that.setState({
type: 'relatedvideo',
headline: card.relatedvideo.headline,
ctext: card.relatedvideo.ctext,
imageUrl: card.relatedvideo.imageUrl
})
}
if ('poll' in card) {
that.setState({
type: 'poll',
headline: card.poll.headline,
subtitle: card.poll.subtitle,
pollId: card.poll.pollId
})
}
if ('imagegallery' in card) {
that.setState({
type: 'imagegallery',
headline: card.imagegallery.headline,
ctext: card.imagegallery.ctext,
imageUrl: card.imagegallery.imageUrl
})
}
if ('profile' in card) {
that.setState({
type: 'profile',
headline: card.profile.headline,
ctext: card.profile.ctext,
imageUrl: card.profile.imageUrl
})
}
if ('newsletter' in card) {
that.setState({
type: 'newsletter',
email: card.newsletter.email
})
}
return card;
};
//Entry Point HERE
var userId = 'O1AB0001', cardStackId = 1;
var json = fetch(userId, cardStackId);
var myCard = getCard(json.cards, this.state.loadCard);
//Set core data
this.setState({
//fulldata
fullData: json,
//card stack
userId: json.cardStack.name,
cardStack: json.cardStack.id,
//card
cardId: myCard.id,
socialButton: myCard.socialButton,
order: myCard.order,
sponsorUrl: myCard.sponsorUrl,
logoUrl: myCard.logoUrl,
meta: myCard.meta,
name: myCard.name
});
},
setNew: function (nextState) {
var nsFullData = nextState.fullData;
var nsCards = nsFullData.cards;
var nsCardStack = nsFullData.cardStack;
var that = this;
var getCard = function (cardArray, cardOrder) {
var card;
for (var key in cardArray) {
if (cardArray[key].order == cardOrder) {
card = cardArray[key];
}
}
if ('product' in card) {
that.setState({
type: 'product',
headline: card.product.headline,
subtitle: card.product.subtitle,
ctext: card.product.ctext,
imageUrl: card.product.imageUrl,
price: card.product.price
})
}
if ('article' in card) {
that.setState({
type: 'article',
headline: card.article.headline,
ctext: card.article.ctext
})
}
if ('map' in card) {
that.setState({
type: 'map',
mapCoordinates: card.map.mapCoordinates
})
}
if ('relatedvideo' in card) {
that.setState({
type: 'relatedvideo',
headline: card.relatedvideo.headline,
ctext: card.relatedvideo.ctext,
imageUrl: card.relatedvideo.imageUrl
})
}
if ('poll' in card) {
that.setState({
type: 'poll',
headline: card.poll.headline,
subtitle: card.poll.subtitle,
pollId: card.poll.pollId
})
}
if ('imagegallery' in card) {
that.setState({
type: 'imagegallery',
headline: card.imagegallery.headline,
ctext: card.imagegallery.ctext,
imageUrl: card.imagegallery.imageUrl
})
}
if ('profile' in card) {
that.setState({
type: 'profile',
headline: card.profile.headline,
ctext: card.profile.ctext,
imageUrl: card.profile.imageUrl
})
}
if ('newsletter' in card) {
that.setState({
type: 'newsletter',
email: card.newsletter.email
})
}
return card;
};
var myCard = getCard(nsCards, this.state.loadCard);
this.setState({
//fulldata
fullData: nsFullData,
//card stack
userId: nsCardStack.name,
cardStack: nsCardStack.id,
//card
cardId: myCard.id,
socialButton: myCard.socialButton,
order: myCard.order,
sponsorUrl: myCard.sponsorUrl,
logoUrl: myCard.logoUrl,
meta: myCard.meta,
name: myCard.name
});
},
componentWillUpdate: function (nextProps, nextState) {
if (nextState.loadCard !== this.state.loadCard) {
this.setNew(nextState);
}
},
render: function () {
return (
<div className='sg-cardBase'>
<div className='sg-cardHeaderSection'>
<CardHeader setLoadCard={i => this.setState({loadCard: i})} data={this.state}/>
</div>
<div className='sg-cardContentSection'>
<CardContent data={this.state}/>
</div>
<div className='sg-cardFooterSection'>
<CardFooter data={this.state}/>
</div>
</div>
);
}
});