Shashika Virajh
Shashika Virajh

Reputation: 9487

ReactJS: Create reusable table row component with dynamic content

In my application, I have the following code which I want to make reusable. I tried to make a component based on the following code, however the <td> content has several type and can vary. In some cases I need the content of the first <td> to be a string, while in other cases I need it to be a <Button>.

How can I achieve dynamic content like this in the first <td> of a reusable component?

const educationList = props.education.map(edu => (
  <tr key={edu.id}>
    <td>{edu.school}</td>
    <td>{edu.degree}</td>
    <td>
      <Moment format="YYYY/MM/DD">{edu.from}</Moment> -
      {edu.to === null ? (
        ' Now'
      ) : (
        <Moment format=" YYYY/MM/DD">{edu.to}</Moment>
      )}
    </td>

    <td>
      <Button
        className="btn btn-danger"
        text="Delete"
        onClick={() => props.deleteEducation(edu.id)}
      />
    </td>
  </tr>
))

Upvotes: 1

Views: 1522

Answers (2)

Dacre Denny
Dacre Denny

Reputation: 30390

If I understand your question correctly, perhaps you could define a generic <TableRow> component as shown below, where:

  • the same general table row structure is defined and can be reused
  • the contents of the first <td> of the <TableRow> can be specified externally, allowing you to render dynamic content into the common surrounding row structure

TableRow

/* Define TableRow functional component. This allows reuse of code for general row
structure while also allowing external control over the contents of the first <td> 
*/
const TableRow = (props) => {

    const { education } = props;

    return (<tr key={education.id}>
        { /* Render the children components of this TableRow via props.children */ }
        <td>{ props.children }</td>
        <td>{education.degree}</td>
        <td>
        <Moment format="YYYY/MM/DD">{education.from}</Moment> -  
        {education.to === null ? ' Now' : <Moment format=" YYYY/MM/DD">{education.to}</Moment> }
        </td>
        <td>    
        <Button
            className='btn btn-danger'
            text='Delete'
            onClick={() => props.deleteEducation(education.id)} />
        </td> 
    </tr>)
}

Usage

{ /* Example of how to use TableRow */ }
const educationList = props.education.map(edu => ( 
    <React.Fragment>

        { /* Render a button in first <td> of table row */ }
        <TableRow education={edu} deleteEducation={this.deleteEducation} >
            <button>Example button row</button>
        </TableRow>

        { /* Render another table row with string in first <td> of table row */ }
        <TableRow education={edu} deleteEducation={this.deleteEducation} >
            { `Example string row` }
        </TableRow>

    </React.Fragment>))

Please note, the purpose of this usage example is to illustrate how <TableRow> can be used to render different types of content in the first <td> of your common table row structure and is not indicative of how you would actually make use this component in your code.

Hope this helps!

Upvotes: 1

kenodek
kenodek

Reputation: 372

That's already a component but stateless. If you want to make it a class it should looks like that

class EducationList extends React.Component() {
constructor(){
    super()
}

const educationList = props.education.map(edu => ( 
    <tr key={edu.id}>
       <td>{edu.school}</td>
       <td>{edu.degree}</td>
       <td>
          <Moment format="YYYY/MM/DD">{edu.from}</Moment> -  
          {edu.to === null ? ' Now' : <Moment format=" YYYY/MM/DD">{edu.to}</Moment> }
       </td>

       <td>    
          <Button
             className='btn btn-danger'
             text='Delete'
             onClick={() => props.deleteEducation(edu.id)}
          />
       </td> 
    </tr>
 ));  

 render() {
     return(
        {educationList}
     )
 }

}

Upvotes: 0

Related Questions