gene b.
gene b.

Reputation: 11984

Can't read state variable from inside React-Table Column Definition (React.useMemo)

I'm using React-Table. There is a column definition that occurs as React.useMemo as follows:

const columns = React.useMemo(
    () => [
        {
            Header: "approverId",
            accessor: "approverId",
            isVisible: false
        },
        {
            Header: "Assigned Approver",
            accessor: "assignedApproverName",
            isVisible: true,
        },
        // Note this final Action column containing a Button
        {
            Header: "Action",
            accessor: "id",
            isVisible: true,
            disableSortBy: true,
            disableGlobalFilter: true,
            Cell: ({ cell }) => (
                <div className="table-button-wrapper">
                    
                    <Button onClick={() => setVars(cell.row.values,'edit')} variant="primary" size="sm" className="btn-slim" title="Edit" data-tip='Edit'><i className="fa fa-pencil" aria-hidden="true"></i></Button>
                
                </div>
            )
        }],

The last Action column defines a Button which should call a component function, setVars, on onClick. When I get to that function, I have some state variables (all within the same component) that I need to examine, but they are NULL inside that function (which they should not be).

const [approverList, setApproverList] = useState(null);
// approverList is set on useEffect([]) correctly upon initialization, 
// verified (printed its contents in component)

function setVars(values, mode) {
    // This state var. should not be NULL, but is NULL when called from the React-Table column
    if (approverList != null) {
        //...
    }
}

I verified in the debugger that:

  1. approverList is not NULL, and filled out in the component, before the button is clicked
  2. the issue has to do with this React-Table memo, everywhere else the variable is read fine

Upvotes: 2

Views: 933

Answers (2)

Hesham Alamam
Hesham Alamam

Reputation: 1

you have to make CustomCell Component

{
        Header: "Action",
        accessor: "id",
        isVisible: true,
        disableSortBy: true,
        disableGlobalFilter: true,
        Cell: ({ cell }) =><CustomCell cell={cell}/>
    }
export const CustomCell = (cell)=>{
const [vars , setVars ] = useStats<any>(null)
return (
    <div className="table-button-wrapper">
                    
        <Button onClick={() => setVars(cell.row.values,'edit')} variant="primary" size="sm" className="btn-slim" title="Edit" data-tip='Edit'><i className="fa fa-pencil" aria-hidden="true"></i></Button>
    
    </div>
)

}

Upvotes: -1

Yan Digilov
Yan Digilov

Reputation: 296

You have to make sure that the second argument inside of useMemo is keeping track of the changing state. So if you are seeing a change in the approverList state, you have to use the following column definition:

    const columns = useMemo(()=>[
        {
            Header: "approverId",
            accessor: "approverId",
            isVisible: false
        },
        {
            Header: "Assigned Approver",
            accessor: "assignedApproverName",
            isVisible: true,
        },
        // Note this final Action column containing a Button
        {
            Header: "Action",
            accessor: "id",
            isVisible: true,
            disableSortBy: true,
            disableGlobalFilter: true,
            Cell: ({ cell }) => (
                <div className="table-button-wrapper">
                    
                    <Button onClick={() => setVars(cell.row.values,'edit')} variant="primary" size="sm" className="btn-slim" title="Edit" data-tip='Edit'><i className="fa fa-pencil" aria-hidden="true"></i></Button>
                
                </div>
            )
        }]

, [approverList])

Upvotes: 2

Related Questions