Why isn't the component rendered after overwriting the array?

  • 0
    The essence of the question is as follows. There is an array of elements. After the main render, I rebuild it 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 received container. I write the elements that do not fit into a separate array inside the main one.

    Everything is done on hooks. I write the reassembled (mutated main) array through hooks (use {variable}). However, the re-rendering does not happen, it happens 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?

    Code under the spoiler:
    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);

    React Anonymous, Dec 3, 2020

  • 2 Answers
  • 0
    The problem has been resolved. It turned out that he was not correctly passing the array for rewriting into a variable.



    The following code worked for me:

    let elements = [...items]

    //DO SOMETHING

    setItems(elements)

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

    setItems([...elements, exampleArray])
    Anonymous

  • 0
    In theory, it should solve the problem.

    useEffect (updateWidthElements, [items])
    Anonymous

Your Answer
To place the code, please use CodePen or similar tool. Thanks you!