【问题标题】:Toggle div-elements in different component in React在 React 中切换不同组件中的 div 元素
【发布时间】:2017-09-15 12:33:48
【问题描述】:

我对 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?看起来我无法从该组件传递任何道具,因为它是“独立”组件?

【问题讨论】:

  • 这两个组件有什么关系? onClickFunction 函数在哪里?
  • 抱歉,没有。那只是我留下的摆弄。现在添加了评论之间的功能。
  • 如果代码不相关 - 删除它。如果它是相关的 - 确保有一个连接..
  • 组件之间没有连接,它们只是从上层组件获取相互的props。
  • 所以添加上层组件,这样我们就可以理解上下文了。

标签: javascript jquery reactjs toggle


【解决方案1】:

你需要lift the state up

当然,你也可以使用 Redux 来解决这个问题,但让我们保持简单,只使用 React。

提升状态

创建一个同时包含&lt;Navigation /&gt;&lt;ListGenres /&gt; 组件的组件。

在这个父组件中保留状态(genreselectedGenre)并通过 props 向下传递。

您还需要创建回调来处理类型更改。

示例如下:

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>
    )
  }
}

【讨论】:

  • 是的,这成功了!这就是我基本上想要做的,提升状态!谢谢你,先生!
【解决方案2】:

您没有提供太多关于事情应该如何工作的代码或示例,但据我了解,您正在寻找类似于选项卡的行为,您单击选项卡并显示相应的视图。
如果是这种情况,那么您需要一个父组件来管理选定的选项卡并分别呈现视图。 这是一个简单的例子:

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>

【讨论】:

    猜你喜欢
    • 2021-12-06
    • 1970-01-01
    • 2021-06-11
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多