Search code examples
javascriptreactjsclosuresag-gridag-grid-react

Reactjs closure when passing state to component


I got a react functional component:

const DataGrid = (props) =>
{          
    const [containerName, setContainerName] = useState("");                                                                   
    const [frameworkComponents, setFrameworkComponents] = useState(
      {customLoadingOverlay: LoadingOverlayTemplate,
      customNoRowsOverlay: UxDataGridCustomNoRows,
      editButton: params => <ViewAndDeleteSetting {...params}  
                                                  openAddConfigurationsWindow={openAddConfigurationsWindow}
                                                  onDeleteSetting={onDeleteSetting}/>,
     });

useEffect(async () =>
    {
      if(props.containerName && props.containerName !== "")
      {
        setContainerName(props.containerName);
      }
    },[props.containerName]);
.
.
.
const onDeleteSetting = async (settingKey) =>
{
  console.log("ON DELETE AND CONTAINER NAME:");
  console.log(containerName); //HERE THE CONTAINER NAME IS EMPTY
   ...
}
return (
  <UxDataGrid 
            frameworkComponents={frameworkComponents}/>
);

The container name inside useEffect exists and is not empty. As you can see in the comment in onDeleteSetting, the containerName is empty when this callback is invoked. I tried adding this to the useEffect after setContainerName:

setFrameworkComponents({customLoadingOverlay: LoadingOverlayTemplate,
        customNoRowsOverlay: UxDataGridCustomNoRows,
        editButton: params => <ViewAndDeleteSetting {...params}  
                                                         openAddConfigurationsWindow={openAddConfigurationsWindow}
                                                         onDeleteSetting={onDeleteSetting}/>,
            });

That didn't work.

How can I get the name inside the callback? There is no special need to leave that frameworkComponents struct in the state.. it can also be moved to somewhere else if you think its better


Solution

  • The problem was with how I tried passing props to ViewAndDeleteSetting. If you want to pass prop to a cell rendered component, you shouldn't be doing it in frameworkComponents, but rather you need to do it in the column definition like this:

    useEffect(() =>
    {
      let columns = [{headerName: '', cellRenderer: 'editButton', width: 90, editable: false, 
                      cellRendererParams: {
                        openAddConfigurationsWindow: openAddConfigurationsWindow,
                        onDeleteSetting: onDeleteSetting
                    }},
                    .. other columns
                    ]
    
      setColumnDefinition(columns);
    },[props.containerName]);
    

    The columns with the cellRendererParams do gets recreated in the useEffect when the name changes, and then the component can access this params regularly via its props