Custom Block Class with custom Template, cache issue I need add a custom block in my website, this block must show some users values (from customs fields).

I can show all user variables I want but if a user value change for some reason, I must clear all caches for get the news values from the page where is showed my custom block. 

I checked the drupal 8 cache API and try find some example, but I don't find how I do for my variables aren't cached. (or cached but refresh when datas user change)

My code is very simple, I have this hook theme (in my .module) : 

function main_menu_theme($existing, $type, $theme, $path)
{
  $theme=array();
  $theme['block__main_menu_quick_stat_block'] = array(
    'base hook' =&gt; 'block',
    // 'render element' =&gt; 'block', // I tried with and without this line..
  );
  return $theme;
}


This is the build method from my Block Class: 

class MainMenuQuickStatBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {
    $build = [];

    // Get the currect Drupal User
    $user = _getCurrentUser();

//I tried this...
//  $build['main_menu_quick_stat_block'] = array(
//    '#one' =&gt; $user-&gt;customfieldone-&gt;value,
//    '#two' =&gt; $user-&gt;customfieldtwo-&gt;value,
//  );
//  return $build;

//I tried this...
//    return array(
//      'main_menu_quick_stat_block' =&gt; array(
//        '#cache' =&gt; array('max-age' =&gt; 0),
//        '#one' =&gt; $user-&gt;customfieldone-&gt;value,
//        '#two' =&gt; $user-&gt;customfieldtwo-&gt;value,
//      ),
//    );

//Last try..  
    return array(
        '#one' =&gt; $user-&gt;customfieldone-&gt;value,
        '#two' =&gt; $user-&gt;customfieldtwo-&gt;value,
        '#cache' =&gt; [
          'max-age' =&gt; 0,
          // 'contexts' =&gt; ['user',], // I tried this
          // 'contexts' =&gt; 'user', // I tried this
        ],
    );
  }
}


For my custom template, I copied the default block.html.twig template from the theme directory.
I can show variables "one" and "two" from the webpage thanks to the custom template. But impossible to configure theses variables for they become uncacheable ! 

I also try with cache tags but no success..



EDIT 1 (after 4k4 detailed answer !)

This is my last try : 
From my custom Block Class : 

class MainMenuQuickStatBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {
    $build = [];
    $user = \Drupal\user\Entity\User::load(\Drupal::currentUser()-&gt;id());

    //$user = \Drupal::currentUser(); // If I use this way, I get this error in the "'tags' =&gt; $user-&gt;getCacheTags()," below : "Error: Call to undefined method Drupal\Core\Session\AccountProxy::getCacheTags() in Drupal\main_menu\Plugin\Block\MainMenuQuickStatBlock-&gt;build() (line 52 of modules/custom/main_menu/src/Plugin/Block/MainMenuQuickStatBlock.php)."

    $var1 = $user-&gt;field_field1-&gt;value; //If a log var1, I get a value here ($var1 = 7 by example)
    $var2 = 42; //its a test

    return [
        '#theme' =&gt; 'block__main_menu_quick_stat_block',
        '#test' =&gt; 42,
        '#var1' =&gt; $var1,
        '#cache' =&gt; [
          'contexts' =&gt; ['user'],
          'tags' =&gt; $user-&gt;getCacheTags(),
        ],
    ];
  }
}


From my .module file : 

...
function main_menu_theme($existing, $type, $theme, $path)
{
  $theme=array();
  $theme['block__main_menu_quick_stat_block'] = array(
    'variables' =&gt; [
      'var1' =&gt; NULL,
      'test' =&gt; NULL,
    ],
  );

  return $theme;
}


I cleared caches (drush cr)

My custom template block is called when I load the page, but variables 'var1' and 'test' are null. Below, I log variables array with "{{ kint() }}" in my custom template : 



I'm going to find drupal guide for know why my vars are null...
The problem is not your choice of cache parameters. If you set cache max-age to 0 you don't need any other cache setting to disable the cache.

The problem is how you use the block template. You probably render only the single variables you've added and not the default {{ content }} variable. This is the reason the cache info gets lost.

Better use a custom twig template for the custom variables:

hook_theme() in mymodule.module:

function mymodule_theme($existing, $type, $theme, $path) {
  return [
    'mytemplate' =&gt; [
      'variables' =&gt; [
        'var1' =&gt; NULL,
        'var2' =&gt; NULL,
      ],
    ],
  ];
}


build() in block class:

  public function build() {

    $user = \Drupal\user\Entity\User::load(\Drupal::currentUser()-&gt;id());
    $var1 = $user-&gt;field_field1-&gt;value;
    $var2 = $user-&gt;field_field2-&gt;value;

    return [
      '#theme' =&gt; 'mytemplate',
      '#var1' =&gt; $var1,
      '#var2' =&gt; $var2,
      '#cache' =&gt; [
        'contexts' =&gt;  ['user'],
        'tags' =&gt; $user-&gt;getCacheTags(),
      ],
    ];
  };


mytemplate.html.twig:

&lt;h2&gt;Additional user info&lt;/h2&gt;
&lt;p&gt;Field 1: {{ var1 }}&lt;/p&gt;
&lt;p&gt;Field 2: {{ var2 }}&lt;/p&gt;


The template mytemplate will be nested inside of the block template, which then, if you change it back to default, can merge the cache data to the block level and page elements on higher levels.