M
M
McHack2020-11-18 13:41:51
React
McHack, 2020-11-18 13:41:51

Why is the component not rendered after the array is overwritten?

The crux of the matter is as follows. I have an array of elements. After the main render, I rebuild it in due to the fact that the elements simply do not fit in the layout.

I need to do this after the main render because I need to know the width of the resulting container. I write the elements that do not fit into a separate array located inside the main one.

Everything is done on hooks. I write the reassembled (mutated main) array through hooks (use {variable}). However, re-rendering does not occur, it occurs only after changing some simple state (a number or a simple string). Tell me what I'm doing wrong, maybe I should use a different approach?

Spoiler code:

The code

function Menu(props) {
    const [items, setItems] = useState(Object.values(data.ITEMS))
    const [showChild, setShowChild] = useState(0)
    const [windowWidth, setWindowWidth] = useState(window.innerWidth)

    function setChild(e, event) {
      if(showChild > 0 && showChild == e) {
        $('.i_h_menu_child').fadeOut(function () {
          setShowChild(0)
        })
      }
      else
        setShowChild(e)

      event.preventDefault()
    }

    /*function componentDidMount() {
      updateWidthElements()
    }*/

    function addCatalog(arr) {
      let catalog = {
        'ID': 'CATALOG',
        'NAME': 'Каталог',
        'SECTION_PAGE_URL': '',
        'I_CHILD': []
      }

      arr.unshift(catalog)

      return arr
    }

    function updateWidthElements() {
      //setWindowWidth(window.innerWidth)
      let wMenu = document.querySelector('.i_h_menu_react').clientWidth,
        wBody = document.querySelector('.i_body').clientWidth,
        elements = items

      //console.log([wMenu, wBody])

      if(wMenu > wBody) {
        let el = elements.pop()
          //items = items

        if(elements[0]['ID'] == 'CATALOG') {
          elements[0]['I_CHILD'].push(el)
        }
        else {
          elements = addCatalog(elements)
          elements[0]['I_CHILD'].push(el)
        }
        setItems(elements)
        console.log(items)
        //updateWidthElements()
      }
    }
    useEffect(updateWidthElements, [])

    useEffect(() => {
      window.addEventListener("resize", updateWidthElements);
      return () => {
        window.removeEventListener("resize", updateWidthElements)
      };
    })

    return (
      <div className="i_h_menu_react">
        {items.map((item, index) =>
          <div className="i_h_menu_block" key={index}>
            <a href={item.SECTION_PAGE_URL} className="i_h_menu_link" onClick={(e) => setChild(item.ID, e)}>
              <span>{item.NAME}</span>
            </a>
            {item.I_CHILD && showChild == item.ID &&
              <MenuChild items={Object.values(item.I_CHILD)} />
            }
          </div>
        )}
      </div>
    )
  }

  function MenuChild(props) {
    return (
      <div className="i_h_menu_child">
        {props.items.map((item, index) =>
          <div className="i_h_menu_block" key={index}>
            <a href={item.SECTION_PAGE_URL} className="i_h_menu_link">
              <span>{item.NAME}</span>
            </a>
            {item.I_CHILD &&
              <MenuChild items={Object.values(item.I_CHILD)} />
            }
          </div>
        )}
      </div>
    )
  }

  ReactDOM.render(<Menu />, menu_div);

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
McHack, 2020-11-19
@McHack

Problem solved. It turned out that I was not correctly passing the array to be rewritten into a variable.
The following code worked for me:

let elements = [...items]

//DO SOMETHING

setItems(elements)

// Добавление элемента в массив (с методом push у меня не работает)

setItems([...elements, exampleArray])

A
antishock, 2020-11-18
@antishock

In theory it should solve the problem.
useEffect(updateWidthElements, [items])

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question