Home > Blockchain >  ReactJS function doesn't work with setState hook
ReactJS function doesn't work with setState hook

Time:04-12

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:

<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.

CodePudding user response:

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.

  • Related