Home > Net >  React isn't updating child properties in nextjs
React isn't updating child properties in nextjs

Time:07-30

I've tried using event listeners, both in the component directly and as an effect and it does the same thing every time. It just passes the props to child on load and then doesn't update them afterwards.

    const [innerWidthProp, setInnerWidthProp] = useState<number>(0);

    useEffect(() => {
        window.onresize = () => {
            setInnerWidthProp(window.innerWidth)
            console.log(innerWidthProp) 
            // logs inner width on resize.
        }
    }, [innerWidthProp, setInnerWidthProp])


    return (
        <div className='header-container'>
            <NavLinks title={'SOLDIER'} scrollValue={innerWidthProp} onLinkClick={onLinkClick}  />
        </div>
        )
}

And in the child component

console.log(props.scrollValue)
// logs the inner width on load, but doesn't update on resize

I don't understand how the parent props state variables are updating and not the childs...

Update: I feel like this is a nextjs issue as a counter I made, also only updates the parent

Update: I had another parent component which had the function that the use call back was referencing, and had I the state varibles somewhere in the middle of the two components...

This is the code now that it's working

parent.tsx

const Main: NextPage<GithubProps> = ({githubAccountData, githubSubscribe}) => {

    const [innerWidthProp, setInnerWidthProp] = useState<number>();

    const updateWidth = () => setInnerWidthProp(window.innerWidth)
            useEffect(() => {
            window.addEventListener('resize', updateWidth)
            console.log(innerWidthProp)
           updateWidth()
           return () => window.removeEventListener('resize', updateWidth)  
            }, [innerWidthProp, setInnerWidthProp])
    //This useEffect updates the inner width value
    //the inner width value is passed to the child components

    const handleLinkClick = (props: number) => {
        console.log(props)
        window.scrollTo(props, 0)
        //this is the call back function used in the child component
        //this scrolls the page to the value defined in the child component
    }
    return (
        <div> ... </div>
        )

firstchild.tsx

const Header: FunctionComponent<LinkProps> = ({ onLinkClick, innerWidthProp }): JSX.Element => {

    return (
        <div  className='header-container'>
            <NavLinks title={'SOLDIER'} scrollValue={0} onLinkClick={onLinkClick} />
            <NavLinks title={'SOLDIER'} scrollValue={innerWidthProp} onLinkClick={onLinkClick} />
            <NavLinks title={'SOLDIER'} scrollValue={(innerWidthProp)*2} onLinkClick={onLinkClick}/>
            <style jsx>{`
        .header-container{
            position: fixed;
            width: 100vw;
            display: flex;
            flex-direction: row;
            justify-content: space-evenly;
            background-color: rgba(100,100,100, .2);
            z-index: 2;
        }
        `}</style>
        </div>
    );
}
secondchild.tsx

export const NavLinks: FC<NavLinkProps> = ({scrollValue, title, onLinkClick}): JSX.Element => {

    const handleClick = useCallback(() => {
        onLinkClick(scrollValue);
        // scroll values is defined in the parent of this component
        // and this value is a modified version of innerwidth 
    }, [onLinkClick])
    
    return (
        <div>...</div>
        )

CodePudding user response:

You can try this and let me know if it works:

const [innerWidthProp, setInnerWidthProp] = useState<number>(0);

const updateWidth = () => setInnerWidthProp(window.innerWidth)

    useEffect(() => {
       window.addEventListener('resize', updateWidth)
       updateWidth()

       return () => window.removeEventListener('resize', updateWidth)
    }, [])


    return (
        <div className='header-container'>
            <NavLinks title={'SOLDIER'} scrollValue={innerWidthProp} onLinkClick={onLinkClick}  />
        </div>
        )
}

CodePudding user response:

I don't see any problem here, at least with code that you have provided. Try using this snippet. When you run it the parent and child component both console.log the value.

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


const NavLinks = ({scrollValue}) => {
  console.log("Navlinks:", scrollValue)
  return <div></div>

}

export function App(props) {
      const [innerWidthProp, setInnerWidthProp] = useState(0);

    useEffect(() => {
        window.onresize = () => {
            setInnerWidthProp(window.innerWidth)
            console.log("App:",innerWidthProp) 
            // logs inner width on resize.
        }
    }, [innerWidthProp, setInnerWidthProp])


    return (
        <div className='header-container'>
            <NavLinks title={'SOLDIER'} scrollValue={innerWidthProp} onLinkClick={"onLinkClick"}  />
        </div>
        )
}

Console:

Navlinks:
0
App:
0
Navlinks:
1101
App:
1101
Navlinks:
1100
App:
1100
Navlinks:
1099
App:
1099
Navlinks:
1098
App:
1098
  • Related