我如何在React中分别切换多个显示

时间:2018-08-09 23:45:41

标签: javascript reactjs toggle

我有多个帖子是从api请求中获得的。我希望每个帖子都有一个切换开关,以便某人可以单击它,该帖子的其余信息将显示出来。单击“显示更多”切换按钮时,我现在如何设置它打开所有帖子的所有显示。我正在使用NPM react-toggle-display软件包。如何设置它,以便每个帖子都可以同时切换其他帖子的显示?

Posts.js:

import React, {Component} from 'react';
import axios from 'axios';
import styles from './posts.css';
import ToggleDisplay from 'react-toggle-display';

class Posts extends Component {

  constructor(props) {
    super(props)
    this.state = {
      posts: [],
      show : false
    }
  }

  handleClick() {
    this.setState({
      show: !this.state.show
    });
  }


  componentDidMount() {
    axios.get('/api/posts')
    .then(response => {
      console.log(response)
      this.setState({posts: response.data})
    })
    .catch(error => console.log(error))
  }

  render() {
    return (
      <div>
        <h1>Posts</h1>
        <div class="ui section divider"></div>
        {this.state.posts.map((post) => {
          return(
            <div key={post.id}>
              <img class="image" src={post.image}/>
              <p>
                <button onClick={ () => this.handleClick() }>Show More</button>
                {post.title}
              </p>
              <ToggleDisplay show={this.state.show}>
                <p>
                  {post.body}
                </p>
                <p>
                  <div dangerouslySetInnerHTML={{ __html: post.link }} />
                </p>
              </ToggleDisplay>
              <div class="ui section divider"></div>
            </div>
          )
        })}
      </div>
  );
}

}

export default Posts

2 个答案:

答案 0 :(得分:1)

您可以将show做成一个对象,其中每个键都是一个post id并带有布尔值的布尔值,可以用来显示该特定帖子。

示例

class Posts extends Component {
  state = {
    posts: [],
    show: {}
  };

  handleClick = id => {
    this.setState(prevState => ({
      show: { ...prevState.show, [id]: !prevState[id] }
    }));
  };

  componentDidMount() {
    axios
      .get("/api/posts")
      .then(response => {
        console.log(response);
        this.setState({ posts: response.data });
      })
      .catch(error => console.log(error));
  }

  render() {
    return (
      <div>
        <h1>Posts</h1>
        <div class="ui section divider" />
        {this.state.posts.map(post => {
          return (
            <div key={post.id}>
              <img class="image" src={post.image} />
              <p>
                <button onClick={() => this.handleClick(post.id)}>
                  Show More
                </button>
                {post.title}
              </p>
              <ToggleDisplay show={this.state.show[post.id]}>
                <p>{post.body}</p>
                <p>
                  <div dangerouslySetInnerHTML={{ __html: post.link }} />
                </p>
              </ToggleDisplay>
              <div class="ui section divider" />
            </div>
          );
        })}
      </div>
    );
  }
}

答案 1 :(得分:1)

您可以通过几种方法来完成此操作,但基本上可以归结为每个帖子都采用布尔值。

如果要将所有状态保留在posts容器中,则可以在每个post中添加一个字段,以跟踪该post是否打开:

this.setState({posts: response.data.map(post => ({ ...post, show: false }))})

然后渲染切换,如下所示:

<ToggleDisplay show={post.show}>{...}</ToggleDisplay>

另一种方法是创建一个新的Post组件,以跟踪其自身状态。