How to use Bootstrap Modal inside map function in React Js to render indivisual elements?

夙愿已清 提交于 2020-02-05 01:00:13

问题


So I am trying to make a blog application using react js. I am using map function to display all feeds (which I fetched using axios). I am storing these feeds in state and passing them as props. Now the problem is: I am trying to use bootstrap modals in map function to show the content of the blog when button is clicked. I am storing the modal in separate component. However when I click on the button, due to the map function it is iterating through all the elements and showing the last entered data (blog content) for every element in the page inside the modal.

Feed.jsx:

class Feed extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showModal: false,
      modalId: null
    };
  }

  showModal = (e, index) => {
    this.setState({ showModal: true, modalId: index });
    console.log("Index: " + index);
  };

  hideModal = (e, index) => {
    this.setState({ showModal: false, modalId: index });
    console.log("Index: " + index);
  };

  disp(e) {
    console.log("function: " + e._id);
  }

  showArticle(e) {}

  render() {
    let modalClose = () => this.setState({ showModal: false });
    return (
      <div className="container-fluid">
        <ul className="list-group" key={this.props.feedData.id}>
          {this.props.feedData.map(feed => (
            <li
              className="list-group-item"
              style={styles.container}
              key={feed.id}
            >
              <div className="container">
                <div className="col-md-12">
                  <button
                    type="button"
                    className="btn btn-default"
                    onClick={() => this.setState({ showModal: true })}
                  >
                    <h3 style={styles.heading}>{feed.title} </h3>
                  </button>
                  <p>by - {feed.author}</p>
                  <p>{feed.subTitle}</p>
                  <div>
                    <span className="badge">Posted {feed.date}</span>
                    <div className="pull-right">
                      <button className="btn btn-primary">Upvote</button>{" "}
                      <button className="btn btn-info">Comment</button>{" "}
                      <button className="btn btn-danger">Report</button>{" "}
                    </div>
                  </div>
                  <br />

                  <Article

                    show={this.state.showModal}
                    onHide={modalClose}
                    data={feed}
                  />
                  {this.disp(feed)}
                </div>
                <hr />
              </div>
            </li>
          ))}
        </ul>
      </div>
    );
  }
}

Article.jsx

class Article extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  render() {
    console.log("Data from Article.jsx: " + this.props.data.title);
    return (
      <div className="article">
        <Modal
          {...this.props}
          size="lg"
          aria-labelledby="contained-modal-title-vcenter"
          centered
        >
          <Modal.Header closeButton>
            <Modal.Title id="contained-modal-title-vcenter">
              {this.props.data.title}
            </Modal.Title>
          </Modal.Header>
          <Modal.Body>
            <h4> {this.props.data.subTitle} </h4>
            <p>{this.props.data.content}</p>
          </Modal.Body>
          <Modal.Footer>
            <Button onClick={this.props.onHide}>Close</Button>
          </Modal.Footer>
        </Modal>
      </div>
    );
  }
}

I am getting feedData from a parent component which has feeds stored in state from fetch api. console:

The development server has disconnected.
Refresh the page if necessary. webpackHotDevClient.js:65
function: 5cf24b53431f5f089496354b Feed.jsx:25
function: 5cf7a4b26332500efc0d1919 Feed.jsx:25
function: 5cfb558d9198991ea00a9452 Feed.jsx:25
Data from Article.jsx: Liberalism and Loyality Article.jsx:10
Data from Article.jsx: Made my first website Article.jsx:10
Data from Article.jsx: IOT project for tracking heart beat and monitoring data on phone.

How do I use modal for rendering individual feeds ?


回答1:


Its because when you click on the loop is already run when you click on button its rendering the last item data. Better approach would be do not render modal on each loop approach instead it should render on Feed Level Component.

class Feed extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showModal: false,
      modalId: null,
      data:{}
    };
  }

  showModal = (e, index) => {
    this.setState({ showModal: true, modalId: index });
    console.log("Index: " + index);
  };

  hideModal = (e, index) => {
    this.setState({ showModal: false, modalId: index });
    console.log("Index: " + index);
  };

  disp(e) {
    console.log("function: " + e._id);
  }

  showArticle(e) {}
let modalClose = () => this.setState({ showModal: false }); //change

  render() {

    return (
      <div className="container-fluid">
        <ul className="list-group" key={this.props.feedData.id}>
          {this.props.feedData.map(feed => (
            <li
              className="list-group-item"
              style={styles.container}
              key={feed.id}
            >
              <div className="container">
                <div className="col-md-12">
                  <button
                    type="button"
                    className="btn btn-default"
                    onClick={() => this.setState({ showModal: 
                 true,data:feed })} //change
                  >
                    <h3 style={styles.heading}>{feed.title} </h3>
                  </button>
                  <p>by - {feed.author}</p>
                  <p>{feed.subTitle}</p>
                  <div>
                    <span className="badge">Posted {feed.date}</span>
                    <div className="pull-right">
                      <button className="btn btn-primary">Upvote</button>{" "}
                      <button className="btn btn-info">Comment</button>{" "}
                      <button className="btn btn-danger">Report</button>{" "}
                    </div>
                  </div>
                  <br />


                  {this.disp(feed)}
                </div>
                <hr />
              </div>
            </li>
          ))}
        </ul>
               <Article
                    show={this.state.showModal}
                    onHide={this.modalClose}
                    data={this.state.data}
                  />
      </div>
    );
  }
}

Note : Never setState inside render. It will make your app crash.(here modalClose function)



来源:https://stackoverflow.com/questions/56505434/how-to-use-bootstrap-modal-inside-map-function-in-react-js-to-render-indivisual

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!