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
};
ponentDidMount() {
let url = '';
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;
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
};
ponentDidMount() {
let url = 'https://jsonplaceholder.typicode./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;
Share
Improve this question
asked Jan 22, 2019 at 23:19
BasitBasit
3673 gold badges8 silver badges20 bronze badges
0
4 Answers
Reset to default 11You'll need to introduce some additional state on your App
ponent 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
};
ponentDidMount() {
let url = "https://jsonplaceholder.typicode./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>
);
}
}
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>
)
}
Using React Hooks
Create a modal with dynamic props like this
export default function Modal({
open,
setOpen,
onConfirm,
title,
description,
confirmText,
})
Then render the ponent. i did it like this
const getModal = () => {
return (
<Modal open={open} setOpen={setOpen} title={title} description={description} confirmText={confirmText} onConfirm={confirmAction} />
)
}
and then when you want to display your dynamic modal use a function like this ConfirmAction can not be a function you should call the function inside that Modal according to that confirmation
const createModal = (title, description, confirmText, confirmAction) => {
setTitle(title);
setDescription(description);
setConfirmText(confirmText);
setConfirmAction(confirmAction);
setOpen(true);
}
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>
);
});
}