title: Repeater with react
body: <p>I am new to this and learning react at the moment. So i made a custom gutenberg block with 2 repeater fields. 1 is for a name and the second is for a number.</p>
  <p>Technically it works. The fields are repeating etc. But the output i want to realize isn't  working or i dont get it.</p>
  <p>So in the html i want that this block repeat it self but i dont know how.
  If i repeat it once, it works like a charm. When i want to repeat it dubble or more, the output gets under the older output:</p>
  <p>1 Field</p>
  <pre><code>&lt;div class=&quot;skills__skills&quot; &gt;
    &lt;div class=&quot;skills__skill&quot;&gt;
     &lt;p&gt;{ skillnameFields }&lt;/p&gt;
       &lt;div class=&quot;container__bgcolor&quot;&gt;
         &lt;div class=&quot;skills html progress__skill&quot; style={{width:{ percentFields } }}&gt;
            &lt;span&gt;{ percentFields }&lt;/span&gt;
          &lt;/div&gt;
       &lt;/div&gt;
      &lt;/div&gt;
     &lt;/div&gt;
  </code></pre>
  <p>When i want 2 fields this happends:</p>
  <pre><code>&lt;div class=&quot;skills__skills&quot; &gt;
        &lt;div class=&quot;skills__skill&quot;&gt;
         &lt;p&gt;{ skillnameFields }&lt;/p&gt;
         &lt;p&gt;{ skillnameFields }&lt;/p&gt;
           &lt;div class=&quot;container__bgcolor&quot;&gt;
             &lt;div class=&quot;skills html progress__skill&quot; style={{width:{ percentFields } }}&gt;
                &lt;span&gt;{ percentFields }&lt;/span&gt;
                &lt;span&gt;{ percentFields }&lt;/span&gt;
              &lt;/div&gt;
           &lt;/div&gt;
          &lt;/div&gt;
         &lt;/div&gt;
  </code></pre>
  <p>How can i make it work that this happends:</p>
  <pre><code>&lt;div class=&quot;skills__skills&quot; &gt;
        &lt;div class=&quot;skills__skill&quot;&gt;
         &lt;p&gt;{ skillnameFields }&lt;/p&gt;
           &lt;div class=&quot;container__bgcolor&quot;&gt;
             &lt;div class=&quot;skills html progress__skill&quot; style={{width:{ percentFields } }}&gt;
                &lt;span&gt;{ percentFields }&lt;/span&gt;
              &lt;/div&gt;
           &lt;/div&gt;
          &lt;/div&gt;
         &lt;/div&gt;
  
  &lt;div class=&quot;skills__skills&quot; &gt;
        &lt;div class=&quot;skills__skill&quot;&gt;
         &lt;p&gt;{ skillnameFields }&lt;/p&gt;
           &lt;div class=&quot;container__bgcolor&quot;&gt;
             &lt;div class=&quot;skills html progress__skill&quot; style={{width:{ percentFields } }}&gt;
                &lt;span&gt;{ percentFields }&lt;/span&gt;
              &lt;/div&gt;
           &lt;/div&gt;
          &lt;/div&gt;
         &lt;/div&gt;
  </code></pre>
  <p>Here is mine full code:</p>
  <p>I hope some on can help me :)</p>
  <pre><code>    /**
   * BLOCK: project-drie
   *
   * Registering a basic block with Gutenberg.
   * Simple block, renders and saves the same content without any interactivity.
   */
  
  //  Import CSS.
  import './editor.scss';
  import './style.scss';
  
  
  // import components
  import { useBlockProps, RichText, InnerBlocks, MediaUpload, InspectorControls, } from '@wordpress/block-editor';
  
  
  const { __ } = wp.i18n; // Import __() from wp.i18n
  const { registerBlockType } = wp.blocks; // Import registerBlockType() from wp.blocks
  const { Button, IconButton, PanelBody, TextareaControl, TextControl } = wp.components;
  const { Fragment } = wp.element;
  
  
  /**
   * Register: aa Gutenberg Block.
   *
   * Registers a new block provided a unique name and an object defining its
   * behavior. Once registered, the block is made editor as an option to any
   * editor interface where blocks are implemented.
   *
   * @link https://wordpress.org/gutenberg/handbook/block-api/
   * @param  {string}   name     Block name.
   * @param  {Object}   settings Block settings.
   * @return {?WPBlock}          The block, if it has been successfully
   *                             registered; otherwise `undefined`.
   */
  
  
  registerBlockType( 'cgb/block-project-drie-skillbar', {
      title: __( 'project-drie - Skill bar' ), // Block title.
      icon: 'shield', 
      category: 'project drie',
    supports: { 
          align: true,
      }, 
      keywords: [
          __( 'project-drie — CGB skillbar' ),
          __( 'skillbar' ),
          __( 'skill-bar' ),
      ],
    attributes: {
      title: {
        type: 'string',
        source: 'text',
        selector: 'figcaption',
      },
      subtitle: {
        type: 'string',
        source: 'text',
        selector: '.my-content',
      },
      mediaID: {
        type: 'number',
      },
      mediaURL: {
        type: 'string',
        source: 'attribute',
        selector: 'img',
        attribute: 'src',
      },
      skillname: {
              type: 'array',
              default: [],
          },
      percent: {
              type: 'array',
              default: [],
          },
    },
  
      /**
       * The edit function describes the structure of your block in the context of the editor.
       * This represents what the editor will render when the block is used.
       *
       * The &quot;edit&quot; property must be a valid function.
       *
       * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
       *
       * @param {Object} props Props.
       * @returns {Mixed} JSX Component.
       */
  
  
     edit: props =&gt; {
      const { attributes: {title, subtitle, mediaID, mediaURL }, className, setAttributes } = props;
      const onChangeTitle = title =&gt; { setAttributes ( { title } ) };
      const onChangeSubtitle = subtitle =&gt; { setAttributes ( { subtitle } ) };
      const onSelectImage = ( media ) =&gt; { setAttributes( { mediaURL: media.url, mediaID: media.id,} );};
      const handleAddSkillname = () =&gt; {
              const skillname = [ ...props.attributes.skillname ];
              skillname.push( {
                  skill: '',
              } );
              props.setAttributes( { skillname } );
          };
  
      const handleAddPercent = () =&gt; {
              const percent = [ ...props.attributes.percent ];
              percent.push( {
                  percentage: '',
              } );
              props.setAttributes( { percent } );
          };
  
      const handleRemoveSkillname = ( index ) =&gt; {
              const skillname = [ ...props.attributes.skillname ];
              skillname.splice( index, 1 );
              props.setAttributes( { skillname } );
          };
  
      const handleRemovePercent = ( index ) =&gt; {
              const percent = [ ...props.attributes.percent ];
              percent.splice( index, 1 );
              props.setAttributes( { percent } );
          };
  
      const handleSkillnameChange = ( skill, index ) =&gt; {
              const skillname = [ ...props.attributes.skillname ];
              skillname[ index ].skill = skill;
              props.setAttributes( { skillname } );
          };
  
      const handlePercentChange = ( percentage, index ) =&gt; {
              const percent = [ ...props.attributes.percent ];
              percent[ index ].percentage = percentage;
              props.setAttributes( { percent } );
          };
  
      let skillnameFields,
              skillnameDisplay;
  
      let percentFields,
              percentDisplay;
  
          if ( props.attributes.skillname.length ) {
              skillnameFields = props.attributes.skillname.map( ( skillname, index ) =&gt; {
                  return &lt;Fragment key={ index }&gt;
                      &lt;TextControl
                          className=&quot;skillbar__react__name&quot;
                          placeholder=&quot;Add Skill Name. Example: HTML&quot;
                          value={ props.attributes.skillname[ index ].skill }
                          onChange={ ( skill ) =&gt; handleSkillnameChange( skill, index ) }
                      /&gt;
  
                      &lt;IconButton
                          className=&quot;skillbar__remove__react__name&quot;
                          icon=&quot;no-alt&quot;
                          label=&quot;Delete location&quot;
                          onClick={ () =&gt; handleRemoveSkillname( index ) }
                      /&gt;
                  &lt;/Fragment&gt;;
              } );
  
          percentFields = props.attributes.percent.map( ( percent, index ) =&gt; {
                  return &lt;Fragment key={ index }&gt;
                      &lt;TextControl
                          className=&quot;skillbar__react__percent&quot;
                          placeholder=&quot;Add Percent Skill. Example: 50%&quot;
                          value={ props.attributes.percent[ index ].percentage }
                          onChange={ ( percentage ) =&gt; handlePercentChange( percentage, index ) }
                      /&gt;
  
                      &lt;IconButton
                          className=&quot;skillbar__remove__react__percent&quot;
                          icon=&quot;no-alt&quot;
                          label=&quot;Delete location&quot;
                          onClick={ () =&gt; handleRemovePercent( index ) }
                      /&gt;
                  &lt;/Fragment&gt;;
              } );
  
              skillnameDisplay = props.attributes.skillname.map( ( skillname, index ) =&gt; {
                  return &lt;p key={ index }&gt;{ skillname.skill }&lt;/p&gt;;
              } );
  
          percentDisplay = props.attributes.percent.map( ( percent, index ) =&gt; {
                  return &lt;p key={ index }&gt;{ percent.percentage }&lt;/p&gt;;
              } );
          }
  
          return [
        &lt;div className={ className }&gt;
              &lt;InspectorControls key=&quot;1&quot;&gt;
                  &lt;PanelBody title={ __( 'Skill Name' ) }&gt;
                      { skillnameFields }
                      &lt;Button
                          isDefault
                          onClick={ handleAddSkillname.bind( this ) }
                      &gt;
                          { __( 'Add Name' ) }
                      &lt;/Button&gt;
                  &lt;/PanelBody&gt;
            &lt;PanelBody title={ __( 'Percent' ) }&gt;
                      { percentFields }
                      &lt;Button
                          isDefault
                          onClick={ handleAddPercent.bind( this ) }
                      &gt;
                          { __( 'Add percent' ) }
                      &lt;/Button&gt;
                  &lt;/PanelBody&gt;
              &lt;/InspectorControls&gt;
              &lt;div key=&quot;2&quot; className={ props.className }&gt;
            &lt;div className=&quot;wp-block-cgb-block-project-drie-skillbar-repeater&quot;&gt;
              &lt;div className=&quot;wp-block-cgb-block-project-drie-skillbar-repeater-title&quot;&gt;
                &lt;p&gt; Press on Skill bar&lt;/p&gt;
                      &lt;h2&gt;Skill Bar&lt;/h2&gt;
              &lt;/div&gt;
              &lt;div className=&quot;wp-block-cgb-block-project-drie-skillbar-skillname&quot;&gt;
                &lt;h3&gt;Skill Name&lt;/h3&gt;{ skillnameDisplay }
              &lt;/div&gt;
              &lt;div className=&quot;wp-block-cgb-block-project-drie-skillbar-percentage&quot;&gt;
                &lt;h3&gt;percentage&lt;/h3&gt;{ percentDisplay }
              &lt;/div&gt;
            &lt;/div&gt;
              &lt;/div&gt;
          &lt;div className=&quot;wp-block-cgb-block-project-drie-skillbar-info&quot;&gt;
            &lt;div className=&quot;wp-block-cgb-block-project-drie-skillbar-title&quot;&gt;
              &lt;h2&gt;{ __('Title', 'cgb')}&lt;/h2&gt;
                &lt;RichText
                  tagName=&quot;div&quot;
                  className=&quot;wp-block-cgb-block-project-drie-skillbar-titles&quot;
                  placeholder={ __('Add your title here', 'cgb')}
                  onChange={ onChangeTitle}
                  value={ title }
                /&gt;
            &lt;/div&gt;
            &lt;div className=&quot;wp-block-cgb-block-project-drie-skillbar-subtext&quot;&gt;
            &lt;h2&gt;{ __('Sub-Text', 'cgb')}&lt;/h2&gt;
              &lt;RichText
                tagName=&quot;p&quot;
                className=&quot;wp-block-cgb-block-project-drie-skillbar-subtexts&quot;
                value={ subtitle }
                onChange={ onChangeSubtitle }
                placeholder={ __('Add your sub-text here', 'cgb')}
              /&gt;
            &lt;/div&gt;
          &lt;/div&gt;
          &lt;div className=&quot;wp-block-cgb-block-project-drie-skillbar-bgimages&quot;&gt;
            &lt;h2&gt;Right Side Image&lt;/h2&gt;
            &lt;div className=&quot;wp-block-cgb-block-project-drie-skillbar-bgimage&quot;&gt;
              &lt;MediaUpload
                onSelect={ onSelectImage }
                allowedTypes=&quot;image&quot;
                value={ mediaID }
                render={ ( { open } ) =&gt; (
                    &lt;Button className={ mediaID ? 'image-button' : 'button button-large' } onClick={ open }&gt;
                        { ! mediaID ? __( 'Upload Image', 'gutenberg-examples' ) : &lt;img src={ mediaURL } alt={ __( 'Upload Recipe Image', 'gutenberg-examples' ) } /&gt; }
                    &lt;/Button&gt;
                ) }
              /&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
          ];
  
      },
  
      /**
       * The save function defines the way in which the different attributes should be combined
       * into the final markup, which is then serialized by Gutenberg into post_content.
       *
       * The &quot;save&quot; property must be specified and must be a valid function.
       *
       * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
       *
       * @param {Object} props Props.
       * @returns {Mixed} JSX Frontend HTML.
       */
      save: ( props ) =&gt; {
      const {attributes: { title } } = props;
      const {attributes: { subtitle } } = props;
      const {attributes: { mediaURL} } = props;
      const skillnameFields = props.attributes.skillname.map( ( skillname, index ) =&gt; {
              return &lt;p key={ index }&gt;{ skillname.skill }&lt;/p&gt;;
          } );
      const percentFields = props.attributes.percent.map( ( percent, index ) =&gt; {
              return &lt;p key={ index }&gt;{ percent.percentage }&lt;/p&gt;;
          } );
  
      return (
        &lt;section class=&quot;skills_bar&quot;&gt;
          &lt;div class=&quot;container skills__container&quot;&gt;
            &lt;div class=&quot;row skills__row&quot;&gt;
              &lt;div class=&quot;skills__content&quot;&gt;
                &lt;div class=&quot;skills__info col-md-6&quot;&gt;
                  &lt;div class=&quot;skills__text&quot;&gt;
                    &lt;div class=&quot;skills__title&quot;&gt;
                      &lt;h2&gt;{ title } &lt;/h2&gt;
                    &lt;/div&gt;
                    &lt;div class=&quot;skills__subtext&quot;&gt;
                      &lt;p&gt;{ subtitle }&lt;/p&gt;
                    &lt;/div&gt;
                  &lt;/div&gt;
                  &lt;div class=&quot;skills__skills&quot; &gt;
                    &lt;div class=&quot;skills__skill&quot;&gt;
                      &lt;p&gt;{ skillnameFields }&lt;/p&gt;
                      &lt;div class=&quot;container__bgcolor&quot;&gt;
                        &lt;div class=&quot;skills html progress__skill&quot; style={{width:{ percentFields } }}&gt;
                          &lt;span&gt;{ percentFields }&lt;/span&gt;
                        &lt;/div&gt;
                      &lt;/div&gt;
                    &lt;/div&gt;
                  &lt;/div&gt;
                &lt;/div&gt;
                &lt;div class=&quot;skills__images col-md-6&quot;&gt;
                  &lt;div class=&quot;skills__image&quot;&gt;
                    &lt;img src={ mediaURL}/&gt;
                  &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/section&gt;
      );
      },
   } );
  </code></pre>