我对React很新。我正在尝试构建一个可以单击导航项目(在本例中为音乐流派)的网站,它将列出属于该特定类型的所有歌曲。
我的app.js看起来像这样:
import React, { Component } from 'react';
import ListGenres from './ListGenres';
import './App.css';
class App extends Component {
constructor(props) {
super();
this.state = {dataList: props.dataList};
}
render() {
return (
<div>
<div className="App">
<Navigation tracks = {this.state.dataList} />
<ListGenres tracks = {this.state.dataList}/>
</div>
</div>
);
}
}
export default App;
我有一个如下所示的导航组件:
import React from 'react';
import HeaderBar from './HeaderBar';
import MenuItem from 'material-ui/MenuItem';
export class Navigation extends React.Component {
constructor(props) {
super();
}
/*
onClickFunction() {
toggle elements in another component
}
*/
render() {
const genres = this.props.tracks.map((elem) => {
return elem.genre;
});
const filtered = genres.filter((elem, index, self) => {
return self.indexOf(elem) === index;
});
const genreLoop = filtered.map((elem, i) => {
return (
<MenuItem
onClick= {this.onClickFunction}
key={ i }><a>{ elem }</a>
</MenuItem>);
});
return (
<div>
{ genreLoop }
</div>
);
}
}
export default Navigation;
我的项目列表在另一个组件中呈现,如下所示:
import React from 'react';
import './ListGenres.css';
export class ListGenres extends React.Component {
constructor(props) {
super();
}
render() {
return (
<div className="genreList">
<div className="tracklist-visible tracklist-pop">
<ul>
<h3>Pop</h3>
{ this.tracklist('Pop') }
</ul>
</div>
<div className="tracklist-visible tracklist-metal">
<ul>
<h3>Pop</h3>
{ this.tracklist('Metal') }
</ul>
</div>
</div>
);
}
当从导航组件中单击锚点时,是否可以将css-class添加到tracklist-div?看起来我无法传递该组件中的任何道具,因为它是独立的&#34; -component?
答案 0 :(得分:3)
当然,您也可以使用Redux解决这个问题,但让我们保持简单,只使用React。
提升状态
创建一个包含<Navigation />
和<ListGenres />
组件的组件。
将状态(genre
和selectedGenre
)保留在此父组件中,并通过道具向下传递。
您还需要创建一个回调来处理类型更改。
以下是示例:
class App extends Component {
constructor (props) {
super(props)
this.state = {
selectedGenre: null,
genres: [...]
}
}
onGenreChange (genre) {
this.setState({ selectedGenre: genre })
}
render () {
return (
<div>
<Navigation
onGenreChange={genre => this.onGenreChange(genre)}
genres={this.state.genres}
/>
<ListGenres
genres={this.state.genres}
selectedGenre={this.state.genres}
/>
</div>
)
}
}
答案 1 :(得分:1)
您没有提供太多关于事情应该如何工作的代码或示例,但据我了解您正在寻找类似于Tabs的行为,您可以在其中单击Tab并显示相应的视图。
如果是这种情况,那么您需要一个Parent组件来管理所选的Tabs并分别渲染View。
这是一个简单的例子:
const tabs = ["Pop", "Rock", "Rap", "Electro"];
const View = ({name}) => <h1 className="view">{`This is ${name} music!`}</h1>
class Tab extends React.Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}
onClick() {
const { id, onClick } = this.props;
onClick(id);
}
render() {
const { name, id, isSelected } = this.props;
const css = `tab ${isSelected && 'selected'}`;
return (
<div
className={css}
onClick={this.onClick}
>
{name}
</div>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedTab: 1
}
this.onTabChange = this.onTabChange.bind(this);
}
onTabChange(id) {
this.setState({ selectedTab: id });
}
render() {
const { selectedTab } = this.state;
return (
<div>
{
tabs.map((t, i) => {
return (
<div className="wrapper">
<Tab name={t} id={i + 1} isSelected={selectedTab === i + 1} onClick={this.onTabChange} />
{selectedTab == i + 1 && <View name={t} />}
</div>
)
})
}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
.tab {
display: inline-block;
margin: 0 10px;
width: 60px;
text-align: center;
cursor: pointer;
padding: 5px;
}
.selected {
border: 1px solid #eee;
box-shadow: 0 0 3px 1px #999;
}
.wrapper{
display:inline-block;
}
.view{
position: absolute;
top: 0;
left: 0;
margin-top: 50px;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>