リアクションは特定のトップダウン構造を提唱していることを覚えておいてください。各リアクションコンポーネントは可能な限り小道具を使用し、理想的には1つのトップレベルコンポーネントだけが状態を保持する必要があります。
多くの更新された構造を持つcodepenが提供されました。その振る舞いは、あなたが探しているものではないかもしれませんが、コードとそれがどのように編成され、どのように情報がコンポーネント間で共有されて渡されるかを見てください。
レベルがフィルタに適用されたとき(レベルごとに1つ)にレベルを無効にしたり、適用されたフィルタのリストをボタンの色で表示したりするなど、さらに改善が加えられましたまたはタグの結果の上にリストします。
(これらの最新の変更で更新codepen)
[OK]を、あなたのcodepenを持ついくつかの問題があります。
if(getUniqueCategories.indexOf(el.tag) === -1) getUniqueCategories.push(el.tag);
次に、146に再度それを抽出:
は はまず、ライン137上には、オブジェクトからタグアレイ抽出
: return <LevelFilter onClick={boundClick} targetLevel={1} tags={el.tag} />
とを再びレベル2
return <LevelFilter onClick={boundClick} targetLevel={2} tags={el.tag} />
これらの両方の場合:
return <LevelFilter onClick={boundClick} targetLevel={n} tags={el} />
これは、LevelFilterが有効なReactコンポーネント(配列は無効)を返さないという別の問題を明らかにします。
return this.props.tags.filter(tag => tag.taglevel === this.props.targetLevel).map(tag => <a onClick={this.props.onClick}>{tag.name}</a>);
はあなたがなりたい場所に非常に近い試みを持っている必要があり、これらの変更後
return (
<div>
{
this.props.tags
.filter(tag => tag.taglevel === this.props.targetLevel)
.map(tag => <a onClick={this.props.onClick}>{tag.name}</a>)
}
</div>
);
でなければなりません。
さらに調べなければならない問題があります.PHOTODATAではなくタグのリストしかないため、boundClick関数が正しく機能しないなどの問題があります。
、ちょうど最終的な考え。あなたは、あなたのリアクションコンポーネントをもう少し壊したいかもしれません。私はあなたが 、探しているものを行うことができたコンポーネントの下で
var PHOTODATA = [{
"title": "Into the Wild",
"tag": [
{
"name": "Movie",
"taglevel": 1,
"id": 1
},
{
"name": "Adventure",
"taglevel": 2,
"id": 30
},
{
"name": "Book",
"taglevel": 1,
"id": 2
}
],
"info": []
},{
"title": "Karate Kid",
"tag": [
{
"name": "Movie",
"taglevel": 1,
"id": 1
},
{
"name": "Adventure",
"taglevel": 2,
"id": 30
},
{
"name": "Kids",
"taglevel": 3,
"id": 4
}
],
"info": []
},
{
"title": "The Alchemist",
"tag": [
{
"name": "Book",
"taglevel": 1,
"id": 2
},
{
"name": "Adventure",
"taglevel": 2,
"id": 30
},
{
"name": "Classic",
"taglevel": 2,
"id": 4
},
{
"name": "Words",
"taglevel": 4,
"id": 4
}
],
"info": []
}];
var PhotoGallery = React.createClass({
getInitialState: function() {
return {
displayedCategories: []
};
},
selectTag: function (tag) {
this.setState({
displayedCategories: this.state.displayedCategories.concat([tag])
});
},
resetFilter: function(){
this.setState({
displayedCategories: []
});
},
render: function(){
var uniqueCategories = PHOTODATA.map(function (photo) {
return photo.tag; // tag is a list of tags...
}).reduce(function (uniqueList, someTags) {
return uniqueList.concat(
someTags.filter(function (thisTag) {
return !uniqueList.some(function(uniqueTag) {
return uniqueTag.id === thisTag.id && uniqueTag.taglevel === thisTag.taglevel
});
})
);
}, []);
return (
<div className="overlay-photogallery">
<div className="filter-panel"><b>Tags with taglevel 1 only to be displayed</b>
<PhotoGalleryLevel level={1} tags={uniqueCategories} displayedCategories={this.state.displayedCategories} selectTag={this.selectTag} />
<a className="resetBtn" onClick={this.resetFilter}> Reset Filter </a>
</div>
<div className="filter-panel"><b>Tags with taglevel 2 only to be displayed</b>
<PhotoGalleryLevel level={2} tags={uniqueCategories} displayedCategories={this.state.displayedCategories} selectTag={this.selectTag} />
</div>
<div className="PhotoGallery">
<PhotoDisplay displayedCategories={this.state.displayedCategories} photoData={PHOTODATA} />
</div>
</div>
);
}
});
var PhotoGalleryLevel = React.createClass({
render: function() {
var filteredTags = this.props.tags.filter(function (tag) {
return tag.taglevel === this.props.level;
}.bind(this));
var disabled = this.props.displayedCategories.some(function (tag) {
return tag.taglevel === this.props.level;
}.bind(this));
return (
<div>
{filteredTags.map(function (tag){
return <PhotoGalleryButton tag={tag} selectTag={this.props.selectTag} disabled={disabled} />;
}.bind(this))}
</div>
);
}
});
var PhotoGalleryButton = React.createClass({
onClick: function (e) {
this.props.selectTag(this.props.tag);
},
render: function() {
return (
<a className={this.props.disabled} onClick={this.onClick}>{this.props.tag.name}</a>
);
}
});
var PhotoDisplay = React.createClass({
getPhotoDetails: function (photo) {
console.log(this.props.displayedCategories, photo);
return (
<Photo title={photo.title} name={photo.name} tags={photo.tag} />
);
},
tagFilter: function (photo) {
return this.props.displayedCategories.length !== 0 &&
this.props.displayedCategories.every(function(thisTag) {
return photo.tag.some(function (photoTag) {
return photoTag.id === thisTag.id &&
photoTag.taglevel === thisTag.taglevel;
});
});
},
render: function() {
return (
<div>
{this.props.photoData.filter(this.tagFilter).map(this.getPhotoDetails)}
</div>
);
}
});
var Photo = React.createClass({
getTagDetail: function (tag){
return (
<li>{tag.name} ({tag.taglevel})</li>
);
},
sortTags: function (tagA, tagB) {
return tagA.taglevel - tagB.taglevel;
},
render: function(){
return (
<div className="photo-container" data-title={this.props.title} >
{this.props.title}
<ul>
{this.props.tags.sort(this.sortTags).map(this.getTagDetail)}
</ul>
</div>
);
}
});
ReactDOM.render(<PhotoGallery />, document.getElementById('main'));
ニースフォーマットされた質問のように見えるかを確認することができ、あなたの詳細については、私はより良いアプローチのように思えるソリューション –