How to re-render a change in array prototype map in React

Hi everyone,
here is code in React. I dont know how to re-render this array prototype map in React?

import React, { useState, useEffect } from 'react';

const Help = () => {
  const initialObject = [
      {
        fileName: 'Horizon.txt',
        fileSize: 450,
      },
      {
        fileName: 'Something.png',
        fileSize: 2720,
      },
    ],
    [listFiles, setListFiles] = useState(new Map()),
    newVal = {
      fileName: 'TEST',
      fileSize: 0,
    };

  useEffect(() => {
    initialObject.forEach((el) => {
      setListFiles(
        listFiles.set(el.fileName, {
          size: el.fileSize,
        })
      );
    });
  }, []);

  const addNew = () => {
    let temp = listFiles.set('test', newVal);
    setListFiles(temp);
    // after is executed, new value test is in state, but not rendered
  };
  const addNew2 = () => {
    listFiles.set('test', newVal);
    // after execution, new value test is in state, but not rendered
    console.log(listFiles);
  };

  const deleteItem = () => {
    let temp = listFiles;
    temp.delete('Something.png');
    setListFiles(temp);
    console.log(temp);
    // listFiles.delete('Something.png');
  };

  // solution is with counter, observe count nr of map keys in useEffect
  // but is there a better solution?

  return (
    <>
      <button onClick={addNew2}>Add new item into map</button>{' '}
      <button onClick={deleteItem}>Delete Item</button>
      {Array.from(listFiles).map(([key, val]) => {
        return (
          <div key={key}>
            {key} = {val.size}
          </div>
        );
      })}
    </>
  );
};

export default Help;

What is the propper way to pass props to combobox in react

Hi all,
I'm having difficulties to pass Props (Label text) to Combobox component. I usually use same forms for adding and editing Data.
When it comes to editing, If I use lot of arrays to iterate first and then pass right information, I get stucked for hours like here.

I'm using react-select component.

Parent:

import React, { useEffect, useState } from 'react';
import Dropdown2 from './Dropdown2';

function App() {
  const [listCategoriesDb] = useState(
      { term_id: '1', cat_name: 'Uncategorized' },
      { term_id: '2', cat_name: 'simple' },
      { term_id: '3', cat_name: 'grouped' },
      { term_id: '4', cat_name: 'variable' },
      { term_id: '5', cat_name: 'external' },
      { term_id: '6', cat_name: 'exclude-from-search' },
      { term_id: '7', cat_name: 'exclude-from-catalog' },
      { term_id: '8', cat_name: 'featured' }
    ),
    [lbl, setLbl] = useState('');

  useEffect(() => {
    if (listCategoriesDb !== null) {
      let a = listCategoriesDb.find((x) => x.term_id === 3);
      if (a !== undefined) {
        setLbl(a.cat_name);
      }
    }
  }, [listCategoriesDb]);

  return (
    <>
      <div>
        <Dropdown2
          listCategoriesDb={listCategoriesDb}
          initialVal={3}
          lbl={lbl} // If I write here manually, then it will be passed to combobox.
        />
      </div>
    </>
  );
}

export default App;

Child:

import React, { useState } from 'react';
import Select from 'react-select';

export default function Dropdown2(props) {
  const { listCategories, initialVal, lbl } = props,
    [options] = useState(listCategories),
    // here should lbl be populated, but it's not.
    [data, setData] = useState({
      options: {
        value: initialVal, // this is passed
        label: lbl, // this is not passed
      },
    });

  const handleChange = (e) => {
    setData({ ...data, options: e });
  };

  return (
    <div>
      <Select
        defaultValue={data.options}
        onChange={handleChange}
        options={options}
      />
    </div>
  );
}

Thank you!

When using Reducer, object from useState is sent to reducer – why?

Hi,
I have a form in React with few select/input components. Form doesnt get populated when user enters value in them.
Thats the case when I want for input "Username" -> when user starts writing here some username, then React - in Reducer ->
filters array of whole users in background. But then, input components doesnt get populated.

Here is code before render:

let [user, setUserState] = useState({
    username: '',
    email: '',
    firstname: '',
    languageselect: 0
});

let {
    username,
    email,
    firstname,
    languageselect
} = user;

const CheckExistingUserEmail = (parameters) => {
    const { filterby, keyword } = parameters;
    // dont send results to reducer, it will send also user object!! and return nothing
    let a =
      listOnlyUsernameEmail !== null
        ? usersExample.filter((h) => {
            const regex = new RegExp(`${keyword}`, 'gi');
            if (filterby === 'existing_username')
              return h.username.match(regex);
            else return h.email.match(regex);
          })
        : '';
    console.log(a);
  };
// event to populate form elements
const onChange = (e) => {
// works
if (e.target.name === 'languageselect') {
    setUserState({ ...user, id_lang: e.target.value });
    return;
}

if (e.target.name === 'username') {
    // execute filter to show us existing usernames in DB
    if (e.target.value !== '') {
    let parameters = {
        filterby: `existing_${e.target.name}`,
        keyword: e.target.value,
    };
    // Problem is here
    // Both functions do the same thing, filter existing array of data
    // when using local function, input elements gets populated what user is writing
    // when using reducer function, input element doesn't get populated, instead, whole form gets reseted
    // both functions work - they filter array. Only problem is that input doesnt get populated
    // Why?
    CheckExistingUserEmail(parameters); // here - local function | when using this, input is populated
    filterUsernameEmails(parameters); // reducer function | when using this, whole form gets reseted
    } else {
    clearFilterUsernamesEmail();
    }
    setUserState({ ...user, username: e.target.value }); // populate input field when user types sth
    return;
}
// works if not entered something in input username
setUserState({ ...user, [e.target.name]: e.target.value }); // populate the rest of fields in form
};

return {
(...)
<input
    type='text'
    className='px-3 py-3 placeholder-gray-500 text-gray-700 rounded text-sm shadow focus:outline-none focus:shadow-outline w-full ease-linear transition-all duration-150'
    name='username'
    value={username}
    autoComplete='off'
    onChange={(e) => onChange(e)}
/>
}

Code in state/reducer:

// in state
const filterUsernameEmails = (parameters2) => {
    dispatch({ type: FILTER_USERNAME_EMAIL, payload: parameters2 });
};

// in reducer
case FILTER_USERNAME_EMAIL: {
    switch (action.payload.filterby) {
    case 'existing_username':
        return {
        ...state,
        filteredUsernamesEmails: state.listOnlyUsernameEmail.filter((h) => {
            const regex = new RegExp(`${action.payload.keyword}`, 'gi');
            return h.username.match(regex);
        }),
        }; //*/
    case 'existing_email':
        return {
        ...state,
        filteredUsernamesEmails: state.listOnlyUsernameEmail.filter((h) => {
            const regex = new RegExp(`${action.payload.keyword}`, 'gi');
            return h.email.match(regex);
        }),
        };
    }
}

Regex or string replace to add <p> html tag

Hi,
how can I use regex or string replace to add missing "p" tags to sentences without tags.
I tried matching* and splitting first the whole string matching "h" and "pre" tags but dont know how to merge it.

*let regexRule = /<pre>(.|\n|\r\n)[\s\S]*?<\/pre>/g;

Example - input

let someVariable = "Basket
<h1>Fruits</h1>
<pre>Apple
Juice</pre>
<pre>Kiwi</pre>
PVC thing
Trash
<h1>...</h1>";

How can I add "p" tag to Basket, PVC thing and Trash so output would be:

someVariable = "<p>Basket</p>
<h1>Fruits</h1>
<pre>Apple
Juice</pre>
<pre>Kiwi</pre>
<p>PVC thing</p>
<p>Trash</p>
<h1>...</h1>";

Thank you

PHP Trim problem with dots in text

Hi,
I want to replace ticks in text with other text. This method usually works, but when adding three dots, I get php warning
ltrim(): Invalid '..'-range, no character to the right of '..' or invalid range needs to be incrementing.

I don't know where to look for error, except deleting dots.
Here is the code:

$code = "some text before block
´´´´code block1´´´´
text after block
´´´´code block2...´´´´"; // I want ticks to be replaced to this: <pre><code> code block1 </code></pre>

$pattern = "´´´´"; // we are using ticks
$countCodeBlock = substr_count($code, $pattern); // count how many times pattern is written

if ($countCodeBlock > 0 && $countCodeBlock %2 == 0) // check if is pair number of pattern
        {
            for ($i = 0; $i < $countCodeBlock; $i++)
            {
                if ($i%2 == 0) {

                    // first pattern - open a tag
                    // check if text exist before first pattern
                    $getIndex = strpos($code, $pattern);// this is the index of first char of pattern
                    // substr grabs text - input str, start location, length
                    $textBeforeBlock = substr($code, 0, $getIndex); // first text, before first pattern

                    // strlen count char in string
                    if (strlen($textBeforeBlock) > 0) {
                        // show text first
                        echo "<p>" . htmlentities($textBeforeBlock) . "</p>";
                    }
                    // then remove that text and first pattern block
                    // ltrim removes white space, or removes special charaters
                    // ltrim input string, optional character or numbers
                    echo "<pre><code>";
                    $code = ltrim($code, $textBeforeBlock); // first delete text
                    $code = ltrim($code, $pattern); // then delete thoose ticks
                }
                else {
                    // second pattern, and closing a tag
                    $getIndex = strpos($code, $pattern);
                    $textBeforeBlock = substr($code, 0, $getIndex);
                    if (strlen($textBeforeBlock) > 0) {
                        echo htmlentities($textBeforeBlock); // here is the essence of the code text
                    }
                    echo "</code></pre>";
                    $code = ltrim($code, $textBeforeBlock);
                    $code = ltrim($code, $pattern);

                }
            }
            // this is the end of code block, and if there is some rest of text, write it
            if (strlen($code) > 0) {
                echo "<p>" . htmlentities($code) . "</p>";
            }
            else 
                echo "<p></p>"; // this is intentional
        }
        else {
            // there are no ticks in the code variable
            echo "<p>" . "There is no code block:</p><br /><pre>" . htmlentities($code) . "</pre><p></p>";
        }
echo $code;

You can copy code into php sandbox and give a try.