Reputation: 245
I am passing a function to a grandchild (SingleProject) from my parent (App) that opens a model. The grandchild just renders an li in the child (Gallery) that show a list of images(coming from the grandchild). I am trying to get the object from props on the grandchild, pass it back to App, and then through to the modal (Modal) to display the information about the image. The objects that hold the info about the images are stored in a service (module.exports). The openModal function is what is being passed along to the grandchild. The closeModal will be passed to the modal. I am having problems with this. Any help would be appreciated.
//APP (Parent)
class App extends Component {
constructor(props) {
super(props);
this.closeModal = this.closeModal.bind(this);
this.openModal = this.openModal.bind(this);
this.state = {
open: false,
projects: Service,
selectedProject: Service[0]
}
console.log('selectedProject: ', this.state.selectedProject)
}
closeModal(event) {
this.setState({open: false});
console.log('app: ', this.state.open);
}
openModal(event) {
this.setState({open: true});
console.log('app: ', this.state.open);
}
render() {
const show = {
display: 'block'
};
const hide = {
display: 'none'
};
return (
<div>
<div style={this.state.open === false ? hide : show}>
<Modal
value={this.state.open}
closeModal={this.closeModal}
project={this.state.selectedProject}
/>
</div>
<Header />
<Intro />
<WhatIDo />
<WhoIAm />
<Gallery
value={this.state.open}
projects={this.state.projects}
openModal={this.openModal}
/>
<Contact />
<Footer />
</div>
);
}
}
//GALLERY (child)
const Gallery = (props) => {
console.log('props: ', props)
const projectItems = props.projects.map(project => {
return (
<SingleProject
key={project.name}
project={project}
openModal={props.openModal}
/>
);
});
return (
<div className="gallery">
<h3>My Work</h3>
<ul>{projectItems}</ul>
</div>
);
}
//SINGLEPROJECT (grandchild)
const SingleProject = (props) => {
return (
<li className="gallery-images">
<img
src={props.project.img}
onClick={props.openModal}
/>
</li>
);
}
//MODAL (Modal)
const Modal = (props) => {
return(
<div className="modal">
<div
className="modal-close"
onClick={props.closeModal}
/>
<ModalDesc project={props.project} />
</div>
);
}
//SERVICE
module.exports = [
{
name: 'xxx',
img: '.././images/gallery/xxx',
link: 'xxx',
tech: 'AngularJS, jQuery, HTML, CSS, PostgreSQL, Node.js, Gulp, Express.js',
desc: 'A clone of the Texas restaurant Dixie Chicken\'s website featuring a
backend and some parallax effects. This site is not fully responsive.'
},
{
name: 'xxx',
img: '.././images/gallery/xx',
link: 'xxx',
tech: 'AngularJS, jQuery, HTML, CSS, PostgreSQL, Node.js, Gulp, Express.js',
desc: 'A fully responsive clone of the E-commerce website Stance. This was a
group project. I did the set up of the backend, the endpoints, the frontend
state management, the directives, most of the SQL files, the single products
view, the login view, the account view, and the register view.'
},
{
name: 'xxx',
img: '.././images/gallery/xxx',
link: 'xxx',
tech: 'AngularJS, jQuery, HTML, CSS',
desc: 'A fully responsive site for The Battlefield Pilot Club.'
}
];
Upvotes: 2
Views: 515
Reputation: 1093
If I understand what you need correctly, you want to pass the project
information to the openModal
method
You just have to make a small edit to the SingleProject
component
const SingleProject = (props) => {
return (
<li className="gallery-images">
<img
src={props.project.img}
onClick={() => props.openModal(props.project)}
/>
</li>
);
}
and then in your openModal
method you can set the selectedProject
;
openModal(project) {
this.setState({
open: true,
selectedProject: project,
}, () => {
console.log('app: ', this.state.open); // this will print "true"
});
console.log('app: ', this.state.open); // this will print "false"
}
props.onClick
to the onClick
prop of <img/>
we wrap it with an arrow function that will invoke props.onClick
with the project
objectopenModal
method, if you want it to print true
you'll need to print it in the callback to the setState
method since the setState
call does not immediately set the state of the class but rather, react will batch the updates. official documentation for the same hereUpvotes: 1