www.dextsolution.com
DEXTUPLOAD
X5
menu toggleProduct description > React > Cautions

React Cautions

This document summarizes only the items you need to watch when using DEXTUploadX5 (hereinafter X5) in a React environment. Most issues occur when React's re-rendering behavior conflicts with X5's dynamic creation mechanism.

Do not recreate X5 on every re-render

X5 is not a normal HTML element. Internally it is a dynamically created component through dx5.create. Therefore, the configuration must not be such that the X5 creation logic repeats every time the parent component re-renders.

In particular, if unnecessary values are included in the dependency array of the creation useEffect, the existing instance may be cleaned up and loaded again at each re-render.

The creation logic should be limited to reacting only to values that actually require the instance to be recreated.

The props of DEXTUploadX5UI(List/Tile/Single/Grid) components can be categorized as follows depending on whether they cause the internal X5 component to reload when React re-renders.

  • Props that cause the X5 component to reload

    • id
    • type
    • progressType
    • path
    • waitingTime
    • lang
  • Props that do not affect X5 component loading

    • className
    • style
    • hidden
    • columns
    • Props used to configure event handlers
When declaring a wrapper component inside a component

If you declare a function component that wraps an X5 React component inside a parent component, that wrapper component may be treated as a new component every time the parent re-renders.

function Sample() {
  const TestArea = () => {
    return <DEXTUploadX5List id="x5-01" />;
  };

  return <TestArea />;
}

In this structure, X5 may repeatedly unmount and mount. If possible, move the wrapper component outside or apply memoization.

Automatic button binding is not supported

In a React environment, automatic button binding may not work reliably. If the internal module reference at binding time changes during rendering or updates, button events may fire while the actual X5 module object remains empty, which can lead to errors.

In X5 React components, the button binding props have been removed.

Be careful with async state updates inside deletion events

If you call DX5.get(id).getItemById(...) again inside the callback of a React state setter from a deletion-related event, the item may already have been deleted at that point, causing an error.

const [eventLog, setEventLog] = useState([]);

const handleBeforeItemsDelete = (id, arr) => {
  // Reset the event log buffer before deleting files
  setEventLog([]);
};
const handleItemDeleting = (id, itemId) => {
  // Retrieve information about the target to be deleted and record it in the log
  setEventLog(prev => [...prev, `Deleting: ${DX5.get(id)?.getItemById(itemId)?.name}`]);
}
const handleItemsDeleted = (id, count) => {
  // Record the final log after deletion is complete
  setEventLog(prev => [...prev, `Deleted: ${count} files`]);
};

<DEXTUploadX5List ...
  onBeforeItemsDelete={handleBeforeItemsDelete}
  onItemDeleting={handleItemDeleting}
  onItemsDeleted={handleItemsDeleted}
/>

This code repeatedly throws an error indicating an invalid file unique ID. The reason is that by the time the callback passed to the state setter (`setEventLog`) runs, the corresponding item has already been deleted, so querying it with `getItemById` attempts to access an item that no longer exists.

Do not query the necessary item information again inside the state update callback. Instead, extract it into a variable first when the event occurs and use that value.

const handleAItemDeleting = (id, itemId) => {
    const item = DX5.get(id)?.getItemById(itemId); // extract first ↰
    setEventLog(prev => [...prev, `Deleting: ${item?.name}`]);
};
Do not access refs before loading completes

X5 components are loaded asynchronously, so even if a ref is attached, the internal module is not necessarily ready for use immediately.

When conditional rendering is used, the ref may become null again at a certain point. Therefore, access it only after load completion is confirmed, and in general it is recommended to obtain the object through DX5.get(id) after the onCreated event rather than controlling the component object through refs.

Be careful when applying Grid column information initially

In Grid style, if column information is set both through props and in the onCreated event, one setting may overwrite the other depending on the application order.

In particular, if clearColumns() is called in effect code that runs after rendering, the columns added in the creation completion event may be removed again.

It is safer to apply Grid column definitions consistently in only one way and not mix the initial creation timing with later update timing.