Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

ReactJS function doesn't work with setState hook

I have a function that changes the style of a selected row, that works fine without setEntry, with setEntry function all logic of changing style breaks and I don’t know why.

This is the code of function:

const changeStyle = (id, e) => {
    isSelected = true;
    let currentRow = e.currentTarget;
    setEntry(id);

    if (id === previousSelectedId) {
        currentRow.style.backgroundColor = '#FFFFFF';
        isSelected = false;

        if (counter % 2 === 0 && counter !== 4) {
            currentRow.style.backgroundColor = '#f0ffff';
            isSelected = true;
        }
        else {
            currentRow.style.backgroundColor = '#FFFFFF';
            isSelected = false;
        }
    }
    else {
        currentRow.style.backgroundColor = '#f0ffff';

        if (counter > 0) {
            previousSelectedRow.style.backgroundColor = '#FFFFFF';
        }
    }

    counter++;
    previousSelectedRow = currentRow;
    previousSelectedId = id;
};

And this is the HTML where I call the function:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

<div>
        <h4 className="text-center">{name}</h4>
        <div>
            <button className={`${styles.buttons} ${styles['add-button']}`} onClick={addAccount}>+ Add contact</button>
            {entry && <>
                <button className={`${styles.buttons} ${styles['edit-button']}`} onClick={editAccount}>Edit</button>
                <button className={`${styles.buttons} ${styles['delete-button']}`}>Delete</button>
            </>}
        </div>
            </form>
            <TableContainer className={styles.table} component={Paper}>
                <Table sx={{ minWidth: 395 }} aria-label="a dense table">
                    <TableHead>
                        <TableRow>
                            <TableCell className={styles.headers}>Account Type</TableCell>
                            <TableCell className={styles.headers}>Name</TableCell>
                        </TableRow>
                    </TableHead>
                    <TableBody>
                        {accounts.map((account) => (
                            <TableRow
                                key={account.accountExt}
                                sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
                                className={styles.row}
                                onClick={(e) => changeStyle(account[1].id, e)}
                            >
                                <TableCell align="left"><img className={styles.image} src={`data:image/png;base64,${account[1].image}`} alt={account[1].accountInt}></img>{account[1].accountInt}</TableCell>
                                <TableCell align="left">{account[1].accountExt}</TableCell>
                            </TableRow>
                        ))}
                    </TableBody>
                </Table>
            </TableContainer>
        </div>
    </div>

Please help.

>Solution :

It "doesn’t work" because as soon as you update state the component is re-rendering and any manual changes you’ve made to the DOM are immediately lost. Don’t make manual changes to the DOM in React. Instead, rely on state to dynamically render the component.

The state value you have currently is the entry value (presumably, based on the setEntry function). So instead of all that code in the changeStyle function that updates the DOM directly, use the entry value in the rendering to determine the styles.

An example might look something like:

<TableRow
  key={account.accountExt}
  sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
  className={styles.row}
  style={someCondition ? { backgroundColor: '#f0ffff' } : { backgroundColor: '#FFFFFF' }}
  onClick={(e) => changeStyle(account[1].id, e)}
>

Note the style setting on the component. Or if the TableRow component has some other API to set its CSS styling, you’d use that instead. However you structure it, the point is that you’d do this in the rendering and not manually on the DOM.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading