You could reduce the whole structure into a dictionary indexed by item name whose values are dictionaries indexed by dates:
items_dicc = array.reduce((acc, e) => {
  if (!acc[e["item"]["name"]]) {
    acc[e["item"]["name"]] = {
      [e["date"]["name"]]: e["price"]
    }
  } else {
    acc[e["item"]["name"]][e["date"]["name"]] = e["price"]
  }
  return acc
}, {})
/* items_dicc holds:
{ I1: { '202001': 100, '202002': 200 }, I2: { '202002': 300 } }
*/
Subsequently, you could take advantage of the items_dicc structure to build the table you're looking for:
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <table>
    <thead>
      <tr class="thead">
        <th>ITEM</th>
      </tr>
    </thead>
    <tbody class="tbody">
      <tr>
        <td></td>
      </tr>
    </tbody>
  </table>
</body>
<script>
  array = [
    {
      "id": 1,
      "date": {
        "id": 1,
        "name": "202001"
      },
      "item": {
        "id": 1,
        "name": "I1"
      },
      "price": 100
    },
    {
      "id": 2,
      "date": {
        "id": 2,
        "name": "202002"
      },
      "item": {
        "id": 1,
        "name": "I1"
      },
      "price": 200
    },
    {
      "id": 3,
      "date": {
        "id": 2,
        "name": "202002"
      },
      "item": {
        "id": 2,
        "name": "I2"
      },
      "price": 300
    }
  ]
  items_dicc = array.reduce((acc, e) => {
    if (!acc[e["item"]["name"]]) {
      acc[e["item"]["name"]] = {
        [e["date"]["name"]]: e["price"]
      }
    } else {
      acc[e["item"]["name"]][e["date"]["name"]] = e["price"]
    }
    return acc
  }, {})
  // Compute dates that will be used as headers. Duplicates are removed after creating a set and turning it into a list again
  dates = [...new Set(Object.keys(items_dicc).map(i => Object.keys(items_dicc[i])).flat())]
  const thead = document.getElementsByClassName("thead")[0]
  const tbody = document.getElementsByClassName("tbody")[0]
  dates.forEach(date => {
    thead.appendChild(
      htmlToElement(`<th>${date}</th>`)
    )
  });
  Object.keys(items_dicc).forEach(i => {
    let row = `<tr><td>${i}</td>`
    dates.forEach(date => {
      row = `${row}<td>${items_dicc[i][date] || ''}</td>`
    });
    row = `${row}</tr>`
    tbody.appendChild(htmlToElement(row))
  })
  // From https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
  function htmlToElement(html) {
    var template = document.createElement('template');
    html = html.trim();
    template.innerHTML = html;
    return template.content.firstChild;
  }
</script>
</html>
The final result:
<table>
  <thead>
    <tr class="thead">
      <th>ITEM</th>
      <th>202001</th>
      <th>202002</th>
    </tr>
  </thead>
  <tbody class="tbody">
    <tr>
      <td></td>
    </tr>
    <tr>
      <td>I1</td>
      <td>100</td>
      <td>200</td>
    </tr>
    <tr>
      <td>I2</td>
      <td></td>
      <td>300</td>
    </tr>
  </tbody>
</table>
EDIT: Simplest React version of the solution:
App.js
function App() {
  const array = [
    {
      "id": 1,
      "date": {
        "id": 1,
        "name": "202001"
      },
      "item": {
        "id": 1,
        "name": "I1"
      },
      "price": 100
    },
    {
      "id": 2,
      "date": {
        "id": 2,
        "name": "202002"
      },
      "item": {
        "id": 1,
        "name": "I1"
      },
      "price": 200
    },
    {
      "id": 3,
      "date": {
        "id": 2,
        "name": "202002"
      },
      "item": {
        "id": 2,
        "name": "I2"
      },
      "price": 300
    }
  ]
  const items_dicc = array.reduce((acc, e) => {
    if (!acc[e["item"]["name"]]) {
      acc[e["item"]["name"]] = {
        [e["date"]["name"]]: e["price"]
      }
    } else {
      acc[e["item"]["name"]][e["date"]["name"]] = e["price"]
    }
    return acc
  }, {})
  // Compute dates that will be used as headers. Duplicates are removed after creating a set and turning it into a list again
  const dates = [...new Set(Object.keys(items_dicc).map(i => Object.keys(items_dicc[i])).flat())]
  return (
    <div className="App">
      <table>
        <thead>
          <tr>
            <th>ITEM</th>
            {dates.map(date => <th>{date}</th>)}
          </tr>
        </thead>
        <tbody>
          {
            Object.keys(items_dicc).map((item) => {
              return (
                <tr>
                  <td>{item}</td>
                  {dates.map((date) => <td>{items_dicc[item][date] || ''}</td>)}
                </tr>
              )
            })
          }
        </tbody>
      </table>
    </div>
  );
}
export default App;