utopia
utopia

Reputation: 338

Conditional cell rendering in react-table

I have a column for buttons to toggle a modal. The problem is, I don't want to display the button for every single row. I only want to display the button on the first entry of the color. Note that the colors are unpredictable (you don't know what colors will be displayed beforehand).

For example,

color toggler
black    +
red      +
red          //don't display it here
yellow   +
blue     +
blue        //don't display it here
blue        //don't display it here
orange   +
red      +
black    +
black       //don't display it here
blue     +

I have try to go through the document and some example, but I can't seem to find a solution to it (maybe something that I missed ?).

What I did was storing the first color in the state. Then I did with the theCheckFunc:

let flag = true 
if (nextColor !== this.state.color)
 this.setState({color: nextColor})
 flag = false
return flag

Then in the columns I did.

Cell: props => (this.theCheckFunc(props) && <div onClick={somefunc}> + <div>)

However, everything seems to be frozen. The browser doesn't even respond. Any good suggestion on how to do this ?

Upvotes: 2

Views: 13240

Answers (2)

Craig Gehring
Craig Gehring

Reputation: 3377

Don't use state with this, since you don't want to re-render based on new input. Instead, compute the array as part of the render.

For example, assuming that when you get to your render statement, you have a random array of colors like this:

['red', 'red', 'black', 'purple', 'purple']

Then this function could create the array you need with the data for render:

function getTableRowData(arr) {
  let tableRowData = []
  arr.forEach((color, n) => {
    let toggler = true
    if (n !== 0 && arr[n - 1] === color) {
      toggler = false
    }
    tableRowData.push({ color, toggler, })
  })
  return tableRowData
}

Then you can iterate over the tableRowData in your render return and have it display the way you want to.

Upvotes: 2

Yusuf Altıparmak
Yusuf Altıparmak

Reputation: 466

First set your color control variables in state or in class wherever you choose. In this example i'm choosing to control them over state.

constructor(props) {
        super(props);

            this.state = {
                firstRedAlreadyHere: false,
                firstBlueAlreadyHere: false,
                firstGrayAlreadyHere:false,
                ....
                ...
            }
}

then open a function to prepare a table. Later Use that function in render() to put table on component.

function putValuesToTable()
{

    let table = [];

        for (let i = 0; i < (YOUR_LENGTH); i++) {
            {
                let children = [];   /* SUB CELLS */

                /* IF RED COLOR IS NEVER CAME BEFORE, PUT A BUTTON NEAR IT */
                if(!this.state.firstRedAlreadyHere)
                children.push(<td>
                   <SomeHtmlItem></SomeHtmlItem></td> <td><button </button></td>)
                /* ELSE DON'T PUT BUTTON AND CHANGE STATE. */
                else
                {
                  children.push(<SomeHtmlItem></SomeHtmlItem>);
                  this.state.firstRedAlreadyHere = true;
                }
                table.push(<tr>{children}</tr>);
            }
        }
return table;
}

I am changing state directly instead of this.setState(); because I don't want to trigger a refresh :). In render function, call putValuesToTable like this

render()
{
return (<div>
<table>
         <tbody>
         <tr>
         <th>SomeParameter</th>
         <th>SomeParameter2</th>         
         </tr>
             {this.putValuesToTable}
         </tbody>
         </table>
</div>);
}

Use this example to extend your code according to your aim.

Upvotes: 0

Related Questions