0

I have the following property with social icons:

items: {
    type: 'array',
    default: [
      { icon: 'twitter', url: '#' },
      { icon: 'facebook-square', url: '#' },
      { icon: 'youtube', url: '#' },
    ],
 },

I have some controls:

<InspectorControls>
    <PanelBody title={ __( 'Social Network Settings' ) } initialOpen={ true }>

    {items.map( ( item, index ) => (

        <Fragment>

          <SelectControl
            label="Social Network"
            value={ item.icon }
            options={ [
                { label: __( 'Twitter' ), value: 'twitter' },
                { label: __( 'Facebook' ), value: 'facebook-square' },
                { label: __( 'Instagram' ), value: 'instagram' },
                { label: __( 'YouTube' ), value: 'youtube' },
            ] }
            onChange={ ( value ) => setAttributes( { items: [ ...items, { icon: value } ] } ) }
          />

          <TextControl
            label={ __( 'Social Link' ) }
            value={ item.url }
            onChange={ ( value ) => setAttributes( { items: [ ...items, { url: value } ] } ) }
           />

        </Fragment>

    ) ) }

    </PanelBody>
</InspectorControls>

And I'm rendering social icons:

{items.map( ( item, index ) => (
  <a key={ index }
     href={ item.url || '#' }
     target="_blank"
  >
    <FontAwesomeIcon icon={['fab', item.icon]} />
  </a>
) ) }

3 icons are showing. The correct icon name is showing in each select control. However when I change the icon in the select control, a new icon is added, instead of updating. The same goes when adding URLs, blank tags are being added.

How can I update the array when changing the select and text input?

1 Answer 1

1

The onChange logic above implies that a new item will be added on each update.

Your onChangeshould find the correct element and update it accordingly. As example the onChange forSocial Network would look something similar to below. You should implement similar logic for the other onChange too.

onChange={( value ) => {
  const newItem = {...item, icon: value };
  const newItems = [...items];
  newItems[index] = newItem;
  setAttributes({ items: newItems });
}}
Sign up to request clarification or add additional context in comments.

3 Comments

Very cool! Thank you! That works. And to remove items I could just use this? const newItem = {...item, icon: '', url: '' }; That seems to remove the values but not the item ass well from the array.
Or this seems to work but not sure if correct: const array = [...items]; array.splice(index, 1); setAttributes({ items: array });
Hello Panther! I have one more question if you don;t mind... would it be correct to also use const newItems = [...items]; newItems[index].icon = value; setAttributes({ items: newItems }); ? The code seems a little shorter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.