0
votes

After reading the docs for useState and useEffect I cant figure out what i'm doing wrong here... Im trying to dynamically update my h1 title with an updated title when a tab is clicked, however the state will not update so my title wont rerender.

This is my subheader component which takes in an array of objects as props. These objects are iterated over and used to populate the subnav bar. (which works as intended).

const Subheader = (props) => {
    const {
        submenuItems = []
    } = props;

    // State
    const  [pageTitle, setPageTitle] = useState(submenuItems[0].name); //Sets starting value as the first item of my submenu which is also the default route so works as intended.

    const handleMenuItemClick = (name) => {
            setPageTitle(name)
            console.log(name) //This prints out the updated expected value
            console.log(pageTitle) //This prints out the original not updated value

    }

    const submenuItemsJSX = submenuItems.map((item, index) => {
        return (
                <li
                key={index}
                to={item.to}
                onClick={() => handleMenuItemClick(item.name)}
                >
                  <a>
                    {item.name}
                  </a>
                </li>
        )
    });

    useEffect(() => {
      console.log(pageTitle) //This prints out the original not updated value
    }, [pageTitle])


    return (
      <div>
        <div>
          <h1>
            {pageTitle}  //This is what i want to update
          </h1>
        </div>
        <div>
          <ul>
            {submenuItemsJSX}
          </ul>
        </div>
      </div>
    )
}

export default Subheader

a sample of whats coming in through the subMenuItems:

{name: 'Categories', to: '/settings/categories', buttons: [] }
3
Also notice that const [selected? It can't change at all since it's a const.Emile Bergeron
const is fine, please check how to use state in react hook - reactjs.org/docs/hooks-state.html @EmileBergeronwangdev87
Is your confusion with console.log only @William's comment covers that... Or do you actually have some issues with the printed pageTitle value?Nemanja Lazarevic
then pageTitle would be updated inside render.wangdev87

3 Answers

2
votes

setSelectedMenuItem and setPageTitle are the asynchronous method, and you can't get the updated value of selected and pageTitle immediately after setSelectedMenuItem() and setPageTitle().

You should use useEffect to check the updated value with adding dependency.

useEffect(() => {
  console.log(selected)
}, [selected])

useEffect(() => {
  console.log(pageTitle)
}, [pageTitle])
1
votes

Your code appears to be correct. The issue must be somewhere else. I've made a codesandbox demo and everything works.

-1
votes

Have you tried to pass empty string '' to useState, when you declare the pageTitle? And for initialisation of the value you can use useEffect hook.

const [pageTitle, setPageTitle] = useState('');

useEffect(() => {
  setPageTitle(submenuItems[0].name)
})