Meteor react state passed to child component not updating - javascript

On the parent component I am trying to pass down the state ( which are just images ) down to 2 child components. One of the child components just displays the images.
The other child component has an event handler to change one of the images.
Here is my code I am getting no errors yet the image is not changing.. Thanks!
I am not including imports to cut down on code!
Parent component:
export default class Parent extends React.Component{
constructor(){
super();
this.state = {
img1: <img id="img1" className="img-responsive center-block" name="img1" src="img1.png"/>,
img2: <img id="img2" className="img-responsive center-block" name="img2" src="" />
};
}
render(){
return (
<div>
<displayBox layers={this.state}/>
<eventsBox layers={this.state}/>
</div>
)
}
}
This is the display box component:
export default class AvatarCreationBox extends React.Component{
render(){
return (
<div>
{this.props.layers.img1}
{this.props.layers.img2}
</div>
)
}
}
Here is the other child component with the event handler:
It has this event handler that has been tested and works with a console.log at the end of it.
itemClicked(itemId,event){
event.stopPropagation();
if(itemId === "img3"){
this.props.layers.img1 = <img className="media-object" src="img3.png" alt="..."/>;
console.log("yo");
}
}

You need to define a function which manipulates the state in your parent class and pass it as prop. Next step is to call the function with new image inside your event class.
Change your Parent Class to this
export default class Parent extends React.Component{
constructor(){
super();
this.state = {
img1: <img id="img1" className="img-responsive center-block" name="img1" src="img1.png"/>,
img2: <img id="img2" className="img-responsive center-block" name="img2" src="" />
};
this.changeImage = this. changeImage.bind(this)
}
changeImage(newImage){
this.setState({img1: newImage});
}
render(){
return (
<div>
<displayBox layers={this.state}/>
<eventsBox
layers={this.state}
callback={this.changeImage}/>
</div>
)
}
}
and change event box code to following
itemClicked(itemId,event){
event.stopPropagation();
if(itemId === "img3"){
this.props.callback('<img className="media-object" src="img3.png" alt="..."/>');
console.log("yo");
}
}
Update: React components using ES6 classes no longer autobind this to non React methods. In your constructor add
this.changeImage = this. changeImage.bind(this) in the constructor.

Related

Linking Image Issue

I am trying to link my picture but it's not working
Any idea what I have forgotten?
Code:
import React, { Component } from 'react';
export default class Card extends Component {
render() {
return (
<div>
<img src="../img/img_avatar.png" alt="Card"></img>
</div>
);
}
}
[Structure][1]
Images are self-closing tags, so you would use it like:
<img src="../img/img_avatar.png" alt="Card" />
instead of what you're using.

Component is not updating on Button Click, React

I have a parent component 'Menu' and a child component 'DishDetails'. The child component returns a Card on Button Click. It works for the first time when i click on the button. The component is not updated while i again click on button. The Component should update after clicking on the Button.
Parent Component
import React,{Component} from 'react';
import DishDetails from './DishDetails'
import { Card,CardImg,CardImgOverlay,CardTitle,CardBody,CardText} from 'reactstrap'
class Menu extends Component{
//The class base component must have a constructor with super statment
constructor(props){
super(props);
this.state ={
dishSelection:null
}
}
//Method when the user click on the image
onDish(dish){
this.setState({dishSelection:dish})
}
renderDish(dish){
if(dish!=null){
return(
<DishDetails dish = {dish}></DishDetails>
)
}
else{
return(
<div></div>
)
}
}
//The component should implement the render method
render(){
//Declare a variable for the defining the list
const media = this.props.dishes.map((dish)=>{
return(
<div className='col-12 col-md-5 m-2'>
<Card onClick={()=>this.onDish(dish)} key={dish.id}>
<CardImg src={dish.image} alt={dish.name} />
<CardImgOverlay>
<CardTitle>{dish.name}</CardTitle>
</CardImgOverlay>
</Card>
</div>
)
})
return(
<div className='container'>
<div className='row'>
{media}
</div>
<div className='row'>
<div className = 'col-12'>
{this.renderDish(this.state.dishSelection)}
</div>
</div>
</div>
)
}
}
export default Menu;
Child Component
import React , {Component} from 'react'
import {Card,CardImg,CardImgOverlay,CardTitle} from 'reactstrap'
class DishDetails extends Component{
constructor(props){
super(props)
this.state = {
dish : this.props.dish
}
}
render(){
//const dish = this.props.dish;
console.log(this.state.dish.name)
return(
<div>
<div className = 'col-12 col-md-5'>
<Card key={this.state.dish.id}>
<CardImg src={this.state.dish.image} alt={this.state.dish.name} />
<CardImgOverlay>
<CardTitle>{this.state.dish.name}</CardTitle>
</CardImgOverlay>
</Card>
</div>
<div>
</div>
</div>
)
}
}
export default DishDetails;
Constructor fires for the first time only. Don't make copy of props in state if you don't need to change the value inside child component. Change this.state.dish to this.props.dish in child component.
class DishDetails extends Component{
render(){
return(
<div>
<div className = 'col-12 col-md-5'>
<Card key={this.props.dish.id}>
<CardImg src={this.props.dish.image} alt={this.state.dish.name} />
<CardImgOverlay>
<CardTitle>{this.props.dish.name}</CardTitle>
</CardImgOverlay>
</Card>
</div>
<div>
</div>
</div>
)
}
}
export default DishDetails;
Or if you still want to update the state on any change in parent component then you should have a look at this link :-
https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops

How to change Modal state from outside the React class?

I am trying to call my modal by changing the state from outside the react class. But so far no luck. I tried the following:
I have a method named Portfolio which needs to activate the modal once user click on the Image
const Portfolio = (props) =>
<div className="col-sm-4">
<div className="mb-2">
<img
onClick={this.toggle}
className="card-img-top"
src={"/assets/imgs/project/"+props.portfolio.img_thumb}
alt="" />
</div>
</div>
Here is the Class that contain the state and the modal. But I cannot change state to activate the modal.
class Project extends React.Component
{
constructor(props, context) {
super(props, context);
this.state = {
modal: false,
}
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState({
modal: !this.state.modal
});
}
render(){
return (
<div className="row portfolioWrap">
// here resides our modal which activate once modal state changed
<div>
<Modal
isOpen={this.state.modal}
toggle={this.toggle}
className={this.props.className}>
<ModalHeader toggle={this.toggle}>Modal title</ModalHeader>
<ModalBody>
{this.state.gallery.map(gallery =>
<img
className="card-img-top"
src={"/assets/imgs/project/"+gallery} alt="" />)
}
</ModalBody>
<ModalFooter></ModalFooter>
</Modal>
</div>
// calling portfolio method inside the loop
{currentTodos.map(item => <Portfolio key={item.title} portfolio={item} />)}
</div>
)
}
}
I am trying to activate the modal from Portfolio function. But since its outside the class scope i cannot access the state. Is there any way to accomplish this?
You can pass the toggle method to your Portfolio component then use it from the props.
<Portfolio key={item.title} toggle={this.toggle} portfolio={item} />
Then in Portfolio:
const Portfolio = (props) =>
<div className="col-sm-4">
<div className="mb-2">
<img
onClick={props.toggle}
className="card-img-top"
src={"/assets/imgs/project/"+props.portfolio.img_thumb}
alt="" />
</div>
</div>

Onclick event handler with passing this in reactjs

My component is as below:
import React, {PropTypes} from 'react';
export default class Viewdesc extends React.Component {
render() {
return (
<div className="col-md-12 slide-row">
<div className="col-md-12 overview-about-property">
<div className="expandabletext less">
<div className="col-md-12" dangerouslySetInnerHTML={{__html: this.props.record.ABOUT}}></div>
</div>
<div className="showmore"> Show More </div>
</div>
</div>
);
}
}
I want to call function say showmorefunct() passing clicked handler like this in jquery. How can I do this?
You can bind you function and pass params which you want, if you want to. You can do something like :
class Test extends React.Component {
handleClick(param, e){
console.log(e);
console.log(param);
}
render(){
return (
<div className="showmore" onClick={this.handleClick.bind(this, "Some param if you need it")}> Show More </div>
)
}
}
React.render(<Test />, document.getElementById('container'));
Here is fiddle.
UPDATE
http://jsfiddle.net/jwm6k66c/1517/
I don't quite really understand your question, but I imagine you want this-
import React, {PropTypes} from 'react';
export default class Viewdesc extends React.Component {
constructor(props) {
super(props)
this.showMoreFunct = this.showMoreFunct.bind(this)
}
showMoreFunct() {
alert('Show more clicked!')
}
render() {
return (
<div className="col-md-12 slide-row">
<div className="col-md-12 overview-about-property">
<div className="expandabletext less">
<div className="col-md-12" dangerouslySetInnerHTML={{__html: this.props.record.ABOUT}}></div>
</div>
<div className="showmore"> <span onClick={this.showMoreFunct}>Show More</span> </div>
</div>
</div>
);
}
}
You can replace span with a or button. You just need to specify the function you want to call to onClick prop. React will call it automatically when the user clicks on that span.

Handling the a onClick event in React

I'm using the following component to display a list of images in React.
class Viewer extends React.Component{
constructor(props){
super(props);
this.state = {
images : ImageList
};
}
render(){
return (
<div className="row">
<div className="image-viewer">
<ul className="list-inline">
{this.state.images.map(function (image) {
return (<li key={image.mediaId}><a href="#"><img src={image.src}
className="img-responsive img-rounded img-thumbnail"
alt={image.mediaId}/></a></li>);
})}
</ul>
</div>
</div>
);
}
}
I want to trap the onClick event on an image to do some processing, like apply a CSS to put an overlay. How do I do this in React. Please understand I'm rank new to React.
If you update your component to have onClick={this.onImageClick.bind(this, image.mediaId) you can then handle the onClick plus know which image it was that was clicked, save that on state, and use it to apply a className to the image on render (if that's what it is that you want!).
So something like this:
{this.state.images.map(function (image) {
return (<li key={image.mediaId} className={this.state.activeImage === image.mediaId ? 'active' : undefined}><a href="#" onClick={this.onClick.bind(this, image.mediaId)}><img src={image.src} className="img-responsive img-rounded img-thumbnail" alt={image.mediaId}/></a></li>);
})}
And then onClick handler -
onClick: function (mediaId) {
this.setState({activeImage: mediaId});
}

Categories

Resources