Render arrays also existed in the previous versions of Drupal and they were important to the theme system. In Drupal 8, however, they have become the thing--a core part of the Render API that is responsible for transforming markup representations into actual markup.
Acknowledging my limits as a writer, I will defer to the definition found in the Drupal.org documentation that best describes what render arrays are:
Simple, but powerful.
One of the principle reasons behind having render arrays is that they allow Drupal to delay the actual rendering of something into markup to the very last moment. In Drupal 7, often-times as module developers, we would call the actual rendering service on an array in order to turn it into markup,for example, in preprocessor functions so that the resulting strings can be printed in the template. However, this made it impossible to change that data later in the pipeline,for example, in another preprocessor that comes after the one which did the rendering.
For this reason, in Drupal 8, we no longer have to/should render anything manually (except in very specific circumstances). We work with render arrays at all times, including the time up to them being printed in the template. Drupal will know how to turn them into markup. This way, modules and themes can intercept render arrays at various levels in the process and make alterations.
We will now talk about render arrays and the different aspects of working with them.