0
votes

I am new with react, i am just wondering what is best solution for receiving value from component created inside another component, that will be anti patern. I have this 2 components - mainComponent have variable with links for images i just created images and saved value of index from table for picture. In canvas i am rendering this image. I just want to save index of clicked image, creating function that will return value from img object will be good solution? or it is antipatern and i should try another way to implement this?

 class MainComponent extends React.Component {
  
  constructor(){
    super();
    this.imageCol = ['link','link']
    this.state={
        indexOfImage : 0,
    };
  } 
  render() {

    return (
      <div>
        <div>
          {this.imageCol.map((e,index) => {
            return <Image value ={index} source={this.imageCol[index]} key={index} style={this._returnState(index)} />
          })}
        </div>
        <div>
          <ReactCanvas image={this.imageCol[this.state.indexOfImage]}/>
        </div>
      </div>
    );
  }
}

class Image extends React.Component {
  
  constructor(props){
    super(props);
  }

  render() {
    return (
      <img value ={this.props.value} onClick={ ()=>{console.log('click'+this.props.value)} } className={this.props.style} src={this.props.source}/>
    );
  }
}

export default Image;
2
You could pass an onClick event callback prop to Image - deojeff
tried this, but unfortunetly i dont see any response from clicking. Thats propably beacause its not native dom component ( i think so ) - kozi
Can you update your post with the code of how you did it? - deojeff

2 Answers

3
votes

You can simply pass a function to Image component's onclick. That won't be an antipattern. In fact, thats how it should be done.

constructor(){
    ...
  } 
  clickHandler(index){
     console.log("index of the clicked image = "+index)
  }
  render() {

    return (
      <div>
        <div>
          {this.imageCol.map((e,index) => {
            // pass a function as a prop like this
            return <Image onClick={this.clickHandler.bind(this,index)} value ={index} source={this.imageCol[index]} key={index} style={this._returnState(index)} />
          })}
        </div>
        <div>
          <ReactCanvas image={this.imageCol[this.state.indexOfImage]}/>
        </div>
      </div>
    );
  }

Then in the image component simply call the onclick function passed to this as a prop

render() {
    return (
      <img value ={this.props.value} onClick={this.props.onClick} className={this.props.style} src={this.props.source}/>
    );
  }
0
votes

You should pass a function to your Image component that will be called when the user clicks on the image and that updates the state in the MainComponent. Like this:

class MainComponent extends React.Component {

  constructor(){
    super();
    this.imageCol = ['link','link']
    this.state={
        indexOfImage : 0,
    };
  } 

  updateImageIndex(newIndex) {
    this.setState({indexOfImage: newIndex});
  }

  render() {

    return (
      <div>
        <div>
          {this.imageCol.map((e,index) => {
            return <Image onClick={this.updateImageIndex.bind(this)} value={index} source={e} key={index} style={this._returnState(index)} />
          })}
        </div>
        <div>
          <ReactCanvas image={this.imageCol[this.state.indexOfImage]}/>
        </div>
      </div>
    );
  }
}

Note that in the MainComponent I created a new function updateImageIndex() and also passed it as the onClick prop to the Image component. Now, inside the Image component:

class Image extends React.Component {

  constructor(props){
    super(props);
  }

  render() {
    return (
      <img value={this.props.value} onClick={ () => {this.props.updateImageIndex(this.props.value)} } className={this.props.style} src={this.props.source}/>
    );
  }
}

We set the onClick prop that was passed to the Image (React Component) to the <img> onClick event handler. This way, when the user clicks on the image DOM element, the updateImageIndex function will be called and update the state from the MainComponent.