Dynamic content with React js Modal

£可爱£侵袭症+ 提交于 2021-01-21 11:49:19

问题


I want to get dynamic content with React js modal I am using package react-responsive-modal. First I render all the post through map. Now I want when I click the individual post the modal should pop up and show me only that particular post's title and body. Now I can't figure out how to get an individual post in modal. Is it possible to do that via third-party package or I have to make custom modal for that?

import React from 'react';
    import Modal from 'react-responsive-modal';
    import Axios from 'axios';

    const styles = {
        fontFamily: 'sans-serif',
        textAlign: 'center'
    };

    class App extends React.Component {
        state = {
            posts: [],
            open: false
        };

        componentDidMount() {
            let url = 'https://jsonplaceholder.typicode.com/posts';
            Axios.get(url).then(res => {
                this.setState({
                    posts: res.data.slice(0, 10)
                });
                console.log(res.data.slice(0, 10));
            });
        }

        onOpenModal = () => {
            this.setState({ open: true });
        };

        onCloseModal = () => {
            this.setState({ open: false });
        };

        renderPosts() {
            return this.state.posts.map(post => {
                return (
                    <div
                        key={post.id}
                        style={{ width: 400, height: 400, backgroundColor: 'orange' }}
                        onClick={this.onOpenModal}
                    >
                        <h1>{post.title}</h1>
                    </div>
                );
            });
        }

        renderModal(id, title, body) {
            return this.state.posts.map(post => {
                return (
                    <div key={post.id} style={{ width: 400, height: 400, backgroundColor: 'orange' }}>
                        <h1>{post.id}</h1>
                        <h1>{post.title}</h1>
                        <p>{post.body}</p>
                    </div>
                );
            });
        }

        render() {
            const { open } = this.state;
            return (
                <div style={styles}>
                    <h2>react-responsive-modal</h2>

                    <div>{this.renderPosts()}</div>
                    <Modal open={open} onClose={this.onCloseModal} center>
                        <h2>Simple centered modal</h2>
                        <div>{this.renderModal()}</div>
                    </Modal>
                </div>
            );
        }
    }

    export default App;

回答1:


You'll need to introduce some additional state on your App component that keeps track of the currently selected post. In your onOpenModal() method, you can update that state with the index of the post that was clicked. Then, in renderModal(), you can check what the selected post is and only render that post instead of mapping over the entire array.

class App extends React.Component {
  state = {
    posts: [],
    open: false,
    selectedPost: null // Keep track of the selected post
  };

  componentDidMount() {
    let url = "https://jsonplaceholder.typicode.com/posts";
    Axios.get(url).then(res => {
      this.setState({
        posts: res.data.slice(0, 10)
      });
      console.log(res.data.slice(0, 10));
    });
  }

  onOpenModal = i => {
    this.setState({
      open: true,
      selectedPost: i // When a post is clicked, mark it as selected
    });
  };

  onCloseModal = () => {
    this.setState({ open: false });
  };

  renderPosts = () => {
    return this.state.posts.map((post, i) => {
      return (
        <div
          key={post.id}
          style={{ width: 400, height: 400, backgroundColor: "orange" }}
          onClick={() => this.onOpenModal(i)} // Pass the id of the clicked post
        >
          <h1>{post.title}</h1>
        </div>
      );
    });
  }

  renderModal = () => {
    // Check to see if there's a selected post. If so, render it.
    if (this.state.selectedPost !== null) {
      const post = this.state.posts[this.state.selectedPost];
      return (
        <div
          style={{ width: 400, height: 400, backgroundColor: "orange" }}
        >
          <h1>{post.id}</h1>
          <h1>{post.title}</h1>
          <p>{post.body}</p>
        </div>
      );
    }
  }

  render() {
    const { open } = this.state;
    return (
      <div style={styles}>
        <h2>react-responsive-modal</h2>

        <div>{this.renderPosts()}</div>
        <Modal open={open} onClose={this.onCloseModal} center>
          <h2>Simple centered modal</h2>
          <div>{this.renderModal()}</div>
        </Modal>
      </div>
    );
  }
}



回答2:


In the post onClick function set the post id/index in state along with the open flag

Inside the modal render use the saved index/id to pass that post to the modal as a param/prop.

You dont need to map over all posts inside the modal.

Sample

onOpenModal = (index) => {
   this.setState({ open: true, selectedPostIndex: index });
};

onCloseModal = () => {
   this.setState({ open: false, selectedPostIndex: undefined })
}

renderPosts() {
   return this.state.posts.map((post, index) => {
      return (
         <div key={post.id} onClick={() => this.onOpenModal(index)}>
            <h1>{post.title}</h1>
         </div>
      )
   })
}

render() {
....
  <Modal open={open} onClose={this.onCloseModal} center>
    <h2>Simple centered modal</h2>
    <div>{this.renderModal(this.state.posts[this.state.selectedPostIndex])}</div>
  </Modal>
 ....
}

renderModal(post) {
   return (
      <div key={post.id} style={{ width: 400, height: 400, backgroundColor: 'orange' }}>
         <h1>{post.id}</h1>
         <h1>{post.title}</h1>
         <p>{post.body}</p>
      </div>
   )
}



回答3:


Initialize your state with one array which will hold

state = {
        posts: [],
        open: false,
        modalShow: [false,false,false,false,false,false,false,false,false,false] // this is 10 as you have only 10 posts
    };

Now modify render posts

    onOpenModal = (id) => {
        const newModalShow = [...this.state.modalShow];
        newModalShow[id] = true; 
        this.setState({ modalShow: newModalShow});
    };


    renderPosts() {
        return this.state.posts.map((post,index) => {
            return (
                <Fragement>
                <div
                    key={post.id}
                    style={{ width: 400, height: 400, backgroundColor: 'orange' }}
                    onClick={()=>this.onOpenModal(index)}
                >
                    <h1>{post.title}</h1>
                </div>
                <Modal open={this.state.modalShow[index]} onClose={this.onCloseModal} center>
                    <h2>post.title</h2>
                    <div>{this.renderModal()}</div>
                </Modal>
               <Fragement>
            );
        });
    }


来源:https://stackoverflow.com/questions/54317873/dynamic-content-with-react-js-modal

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