0

I'm trying to store an array of strings in the state object under the key of menuHistory, im initialising it with 'first', when the page changes props.location updates, that triggers the useEffect() where I then try to push the location into the array.

The error I'm getting is..

Argument of type '{ menuHistory: number; }' is not assignable to parameter of type 'SetStateAction<{ menuHistory: string[]; }>'.
  Type '{ menuHistory: number; }' is not assignable to type '{ menuHistory: string[]; }'.
    Types of property 'menuHistory' are incompatible.
      Type 'number' is not assignable to type 'string[]'.ts(2345)
import React, {useEffect, useState} from 'react';
import {Link} from 'react-router-dom';

interface propsInterface {
    location: any; 
  }

const SideMenu: React.FC<propsInterface> = (props) => {
  const { global } = useContext(Context) as {global: any; setGlobal: React.Dispatch<React.SetStateAction<any>>};
  const [state, setState] = useState({menuHistory: ['first']});

  useEffect(() => {
    const location = props.location.pathname.split('/')[2];
    setState({menuHistory: state.menuHistory.push(location)});
  }, [props.location])

  return (
    <div className='nav'>
        <Link to={{pathname: '/my/identity'}}><div id='identity'>Identity</div></Link>
        <Link to={{pathname: '/my/accounts'}}><div id='accounts'>Accounts</div></Link>
        <Link to={{pathname: '/my/claims'}}><div id='claims'>Claims</div></Link>
        <hr/>
        <Link to={{pathname: '/my/profile'}}><div id='profile'>Profile</div></Link>
        <Link to={{pathname: '/my/password'}}><div id='password'>Password</div></Link>
        <Link to={{pathname: '/my/settings'}}><div id='settings'>Settings</div></Link>
        <Link to={{pathname: '/my/logout'}}><div id='logout'>Log out</div></Link>
  </div>
  );
}

export {SideMenu};

3 Answers 3

2

like @Clarity said, push returns index of pushed item, also this operator mutates object. Best practice is to create another array (eg. by spreading previous value, like suggested), and add a new entry there, like so:

setState({menuHistory: [...state.menuHistory, location]});
Sign up to request clarification or add additional context in comments.

Comments

2

push return an index of element, use array spread to add the item:

setState(state => ({menuHistory: [...state.menuHistory, location]}));

2 Comments

the error has changed to ` ( </li> Argument of type '(state: { menuHistory: string[]; }) => void' is not assignable to parameter of type 'SetStateAction<{ menuHistory: string[]; }>'. Type '(state: { menuHistory: string[]; }) => void' is not assignable to type '(prevState: { menuHistory: string[]; }) => { menuHistory: string[]; }'. Type 'void' is not assignable to type '{ menuHistory: string[]; }'.ts(2345)`
@Bill I've updated the answer to return the object properly.
1

You have defined {menuHistory: ['first']} which is array . Try using concat instead of push.

   setState({menuHistory: state.menuHistory.concat(location)});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.