Pagination in home page for a custom loop loads same content

Between your question and comments, you say that the purpose of changing the main query is to exclude the most recent post from the main loop on your static home page, becuase it is being displayed as a “hero” post on its own before the rest.

The easiest way to do this is actually using the main loop, and use the pre_get_posts action and found_posts filter to adjust it to remove the most recent post, as follows:

1. Index.php: Get the most recent post(s) using WP_Query

Use a custom query to get the most recent post

<?php 
// custom query to get the most recent post
$the_query = new WP_Query( array('posts_per_page' => '1', 'order' => 'DESC') );

if( $the_query->have_posts() ): 
    while ( $the_query->have_posts() ) : $the_query->the_post(); 
        global $post;  ?>

        [...display post content as required, e.g...]
        <h1><a href="https://wordpress.stackexchange.com/questions/282953/<?php the_permalink();?>"><?php the_title();?></a></h1>
        <?php the_content(); ?>

    <?php endwhile;
endif; 
wp_reset_query();    // Restore global post data stomped by the_post(). 
?>

2. Functions.php: Set up offset and pagination to remove the most recent post(s) from the main loop

Hook into pre_get_posts to adjust the query and pagination for the number of posts to skip, and found_posts filter to adjust the value of number of posts found. Add to functions.php:

/**  Exclude the most recept post from the main query  **/
add_action('pre_get_posts', 'pre_query_homepage_offset', 1 );
function pre_query_homepage_offset(&$query) {

    // only continue if this is the main query on the homepage
    if ( !$query->is_home() || !$query->is_main_query() ) 
        return;

    $posts_to_skip = 1;  // the number of most recent posts to skip
    $posts_per_page = get_option('posts_per_page'); // get posts per page from WP settings

   //Detect and handle pagination...
     if ( !$query->is_paged ) // if we're on the first page...
        $offset = $posts_to_skip; //...just offset by the number of posts to skip
    else 
        // Calculate the page offset if we are not on the first page
        $offset = $posts_to_skip + ( ($query->query_vars['paged']-1) * $posts_per_page );

    $query->set('offset',$offset);  // set the offset for the query
}


/**  Adjust the number of posts found by the main query to account for our offset **/
add_filter('found_posts', 'adjust_homepage_offset_pagination', 1, 2 );
function adjust_homepage_offset_pagination($found_posts, $query) {

    // return the actual value if this isn't the main query on the homepage
    if ( !$query->is_home() || !$query->is_main_query() ) 
        return $found_posts;

    $posts_to_skip = 1; // the number of posts to skip
    return $found_posts - $posts_to_skip;
}

3. Index.php: Display the rest of the posts (excluding the most recent) using the main loop

Instead of using a custom query, now we can use the main loop, as it now has been adjusted to exclude the most recent post by our functions in step 2.

<?php if ( have_posts() ) : 
    while ( have_posts() ) : the_post(); ?>

        [...display post content as required e.g....]
        <h2><?php the_title( ); ?></h2>
        <?php the_content(); ?>

    endwhile;

    // Previous/next page navigation.
    the_posts_pagination( array(
        'prev_text'  => __('&laquo;'),
        'next_text'  => __('&raquo;'),
    ) );

endif;
?>