2

I am very new to react ,Trying to build a app . The basic functionality i am trying to implement is I will have some text ,with a button called show details ,clicking the button will show details regarding the text .

I have the text as well as the details saved as a object array in state

Watcher_list :[
  {
    id:uuid.v4(),
    name : "Memory",
    showdetails : "False"
  },
  {
    id:uuid.v4(),
    name  :"Network",
    showdetails : "False"
  }
]

for the component to render the page the code is as follows

class Watchers extends Component 
{
    showdetails(id)
    {
        this.props.showonclick(id);
    }

    render() {
        if (this.props.item.showdetails ==="True") {

            return (
                <div className="Watchers" >
                    <li>{this.props.item.name}</li>
                    <p1>{this.props.item.id} </p1>
                    <button ref="show details" onClick={this.showdetails.bind(this,this.props.item.id)} > 
                        Show Details 
                    </button>
                </div>
             );}
        else {
            return (
                <div className="Watchers" >
                    <li>{this.props.item.name}</li>
                    <button ref="show details" onClick={this.showdetails.bind(this,this.props.item.id)} > 
                        Show Details 
                    </button>
                </div>
            );
        }  
    }
}

export default Watchers;

the handler for show click just updates the value of showdetails in the state ,ad upon re rendering the details are displayed.

I just wanted to know wether this is the best way to do this ,or is there a much smarter way that I can do the same thing ?

jrenk
  • 1,387
  • 3
  • 24
  • 46
Tanmay Bhattacharya
  • 551
  • 1
  • 5
  • 16

2 Answers2

2

There are a couple of things that you can improve on,

First: you have a lot of redundant code that can be avoided by using conditional rendering like

class Watchers extends Component {
   showdetails(id){
        this.props.showonclick(id);
   }
   render() {
     return (
       <div className="Watchers" >
         <li>{this.props.item.name}</li>
         {this.props.item.showdetails ==="True" ? <p1>{this.props.item.id} </p1> : null }
        <button ref={(ref) => this.showDetails = ref} onClick =
    {this.showdetails.bind(this,this.props.item.id)} > Show Details </button>
    </div>
    );
   } 
}

export default Watchers;

Second: bind inside render is not a good pattern since it creates a new function everytime render is called. Check this answer on how to avoid it.

Third: I don't see any point on why you are using ref looking at the code in your question, but even if you need it, you need to use ref callback like ref={(ref) => this.showDetails = ref} instead of string refs since string refs are a legacy

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • Thanks alot ,this answered most of my doubts ,I basically wanted to know if I was on the right track, and your answer explains it pretty well . I am still not able to understand the ref callback ,ill use the link provided to read up on it . Thanks – Tanmay Bhattacharya Feb 14 '18 at 17:10
  • Yeah, react refs are currently defined using a callback function, the react documentation has a pretty decent explanation on how to use it. – Shubham Khatri Feb 14 '18 at 17:11
1
  1. You need not bind inside render function.
  2. No need to set ref
  3. For a change in ID, you do not require separate conditions. You can use the short circuit operator.

     class Watchers extends Component {
       constructor(props) {
       super(props);
       this.showdetails = this.showdetails.bind(this);
     }
     showdetails(id) {
       this.props.showonclick(id);
     }
     render() {
       return ( 
        <div className = "Watchers">
         <li> {this.props.item.name}</li> 
         {
           this.props.item.showdetails === "True" &&
           <p> {this.props.item.id} < /p>
         } 
         <button onClick = {this.showdetails}>Show Details</button> 
       </div>
    );
    }
    }
    
    export default Watchers;
    

If you are setting state locally, you should probably set showDetails to Boolean true instead of a String like you have provided.

Agney
  • 18,522
  • 7
  • 57
  • 75