0

I have a Material UI submenu being populated from a json. The Main menu item holding this submenu array will be changed according to what is being selected. See image below

enter image description here

The Main menu item holding the submenus looks like this

    <MenuItem
        primaryText={this.state.selectedLanguage.name}
        rightIcon={<ArrowDropRight />}
        style={{userMenuItem}}
        leftIcon={
            <img className="flag" src={this.state.selectedLanguage.icon}/>
        }
        menuItems={languageMenu} //see below
    />

The nested menus are coming from here

    const languageMenu =
        <div>
            {languages.map((item, index) => (
                <MenuItem
                    key={index}
                    onClick={this.onLanguageChange}
                    primaryText={languages[index].name}
                    style={{userMenuItem}}
                    leftIcon={
                        <img className="flag" src={languages[index].icon}/>
                    }/>
            ))}
        </div>

And ultimately, the data is stored in a json like this

const languages = [
    {
        name: 'English',
        icon: './assets/images/flags/uk.png',
        link: ''
    },
    {
        name: 'Español',
        icon: './assets/images/flags/Spain.png',
        link: ''
    },
    {
        name: 'Français',
        icon: './assets/images/flags/France.png',
        link: ''
    }
 ...
];

In my poor understanding of React, I created an initial value for the slected language in the constructor state

constructor(props) {
    super(props);
    this.state = {          
        selectedLanguage:{
            name:"English",
            icon:"./assets/images/flags/uk.png",
        },
    }
}

and a function that will handle the changing (this is my problem area, I'm sure)

onLanguageChange = () => this.setState(
    {
        selectedLanguage: this.state.selectedLanguage.name,
    }
);

I need to build this onChange() function correctly to alter the state based on the submenu clicked. This will give me the groundwork to build other properties that will trigger a translate feature on click as well

Any help will be appreciated. Thanks

2
  • Binding state to MainMenu button like how do you do it in LanguageMenu <img className="flag" src={this.state.selectedLanguage.icon}/> when state change, notify and it change. Read facebook.github.io/react-native/docs/state.html Commented May 20, 2017 at 20:28
  • @botika I changed a few things around. I was able to initiate the value by the state, so that's good because it now reads the state. I can't figure out how to build the onLanguageChange() so that it changes the state values Commented May 20, 2017 at 21:19

2 Answers 2

1

The action needs a parameter - the new language:

onLanguageChange = languageName => this.setState({
    selectedLanguage: languageName
});

and you need to pass it from onClick:

{languages.map((language, index) => (
    <MenuItem
         key={index}
         onClick={() => this.onLanguageChange(language.name)}
         primaryText={language.name}
         style={{userMenuItem}}
         leftIcon={
             <img className="flag" src={language.icon}/>
         }
    />
))}

I am not sure if you want to store language in your state or just the name. Both ways have their uses.

Sign up to request clarification or add additional context in comments.

5 Comments

This cleared up my submenus. It first said language is not defined which I get it because I dont have language anywhere so I used languages (the name of my json data but this resulted in a blank output in the submenus
By the way, the menuitem you posted is the submenu list building a repeater with all the languages in the data and dynamically creating that many menuitems. The click event should take place here but the one that needs to change is the MenuItem in my first block which is the parent menu. The image would give you a visual. Sorry if my code seems unclear. I was trying to avoid putting too much code on here
@LOTUSMS The language is the first parameter of map, which you originally had as item. It doesn't matter where your state is read or stored, it can be used by both your components. Maybe you want to the action to the parent component and keep the state there?
AH! My appologies, I missed that little detail. Ok, the language not defined error went away, but not, when I click on a submenu (i.e portuguese) the main menu is blank. No Errors, It just not receiving the new values. Could it be the onClick() is not updating the state? The main menu is reading from the state.
@LOTUSMS Maybe you want to pass the whole language object to state? e.g. this.onLanguageChange(language)? That's what I was not sure about.
1

Something like this

const languages = [...]


constructor(props) {
    super(props);
    this.state = {          
        selectedLanguage: 0
    }
}

onLanguageChange = (index) => this.setState({ selectedLanguage: index });

const mainMenu =    
    <MenuItem
            primaryText={languages[this.state.selectedLanguage].name}
            rightIcon={<ArrowDropRight />}
            style={{userMenuItem}}
            leftIcon={
                <img className="flag" src={languages[this.state.selectedLanguage].icon}/>
            }
            menuItems={languageMenu} //see below
    />

const languageMenu =
    <div>
        {languages.map((item, index) => (
            <MenuItem
                key={index}
                onClick={this.onLanguageChange(index)}
                primaryText={languages[index].name}
                style={{userMenuItem}}
                leftIcon={
                    <img className="flag" src={languages[index].icon}/>
                }/>
        ))}
    </div>

8 Comments

I updated my code in my orginal question. I don't know if you noticed that before. But the state has both name & icon initiated values there and are being passed to the main menu item. All I need now is for the oinClick to update the state values based on the answer from Sulthan.
Sorry, I forgot one s
Sulthan answer got it working. But you did help me understand the initial build. I appreciate it +1
But is not necessary pass the object to the state when you already have it as a global instance, you are duplicating instances. You're welcome
I will take a look at it. ;)
|

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.