如何在我的组件首次渲染时更新我的​​菜单状态?

如何在我的组件首次渲染时更新我的​​菜单状态?

问题描述:

我有一个用参数调用的应用程序。现在,我的菜单总是加载到默认的MainMenu。我希望能够将状态传递给Menu.js并从打开的不同菜单开始,而不是默认的MainMenu。如何在我的组件首次渲染时更新我的​​菜单状态?

我以为componentWillMount()将使我能够将我的状态设置为我选择的菜单状态,但无论出于何种原因它都不会更新呈现的内容。当我调用它时,this.state.Selected成为我想渲染的正确菜单名称......但实际上并不渲染 - 它最终呈现默认菜单。

所以我必须在componentWillMount()之后调用别的东西来获得它实际渲染?

Landing.js - 调用Menu.js.我想首先渲染菜单'FileOptions'。但是,它目前正在渲染MainMenu。

import React, { Component } from 'react' 
import sass from '../scss/application.scss' 
import PropTypes from 'prop-types' 
import Header from './Header' 
import Menu from './Menu' 
import HelpFile from './HelpFile' 



class Landing extends Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      helpFileName: 'Mainmenu', 
      menuName: 'FileOptions', 
     } 
     } 

    handleHelpChange(helpFileName) { 
     this.setState({helpFileName}); 
    } 

    handleMenuClick(menuName) { 
     this.setState({menuName}); 
    } 

    componentWillMount() { 
     let hlpString = require('electron').remote.getGlobal('sharedObject').hlpOne; 
     if (hlpString != null && hlpString != '.') 
     { 
      this.setState({ 
       helpFileName: hlpString 
      });ss 
     } 
    } 

    render() { 

     return (
      <div> 
       <div> 
        <Header /> 
       </div> 
       <br /><br /> 
       <div className="mainMenuDiv"> 
        <Menu handleHelpChange={this.handleHelpChange.bind(this)} menuName={this.state.menuName}/> 
       </div> 
       <div className="mainContainerDiv"> 
        <HelpFile name={this.state.helpFileName}/> 
       </div> 
      </div> 

     ) 
    } 
} 


export default Landing; 

Menu.js

import React, { Component } from 'react' 
import sass from '../scss/application.scss' 
import PropTypes from 'prop-types' 



class Menu extends Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      Selected: props.menuName,  // reads FileOptions, but still renders MainMenu 
      name: '' 
     } 
     } 

    handleChange(name) { 
     this.setState({ 
      name: name 
     }); 
    } 

    handleClick(e, num) { 
     this.setState({ 
      name: num 
      },() => { 
      let helpFileName = num; 
      helpFileName = helpFileName.toLowerCase().trim(); 
      //Cap the first letter in the name and add the rest of the name 
      helpFileName = helpFileName.charAt(0).toUpperCase() + helpFileName.substr(1); 
      this.props.handleHelpChange(helpFileName); 
      }); 
     } 

    handleMenuClick(e, num, opt) { 
     this.setState({ 
      name: num, 
      Selected: opt 
      },() => { 
      let helpFileName = num; 
      helpFileName = helpFileName.toLowerCase().trim(); 
      //Cap the first letter in the name and add the rest of the name 
      helpFileName = helpFileName.charAt(0).toUpperCase() + helpFileName.substr(1); 
      this.props.handleHelpChange(helpFileName); 
      }); 
     } 

    render() { 
     const MainMenu =() => (
      <div> 
       <button 
        label="File Options" 
        //onClick={() => this.setState({ Selected: FileOptions })} 
        onClick={(e) => this.handleMenuClick(e, 'Fileopt', FileOptions)} 
        className="aMenuButton" 
       >FILE OPTIONS</button> 
       <button 
        label="Setup Options" 
        onClick={(e) => this.handleMenuClick(e, 'Setupopt', SetUpOptions)} 
        className="aMenuButton" 
       >SETUP OPTIONS</button> 
       <button 
        label="Lumber Options" 
        onClick={(e) => this.handleMenuClick(e, 'Lumberopt', MoreOptions)} 
        className="aMenuButton" 
       >MORE OPTIONS</button> 
       <button 
        label="Main Menu" 
        onClick={(e) => this.handleClick(e, 'Mainmenu')} 
        className="aPrevButton" 
       >MAIN MENU</button> 
      </div> 
     ); 

     const FileOptions =() => (
      <div> 
       <button 
        label="Option One" 
        onClick={(e) => this.handleClick(e, 'Option One')} 
        className="aMenuButton" 
       >Option One</button> 
       <button 
        label="Option Two" 
        onClick={(e) => this.handleClick(e, 'Option Two')} 
        className="aMenuButton" 
       >Option Two</button> 
       <button 
        label="Option Three" 
        onClick={(e) => this.handleClick(e, 'Option Three')} 
        className="aMenuButton" 
       >Option Three</button> 
       <button 
        label="Option Four" 
        onClick={(e) => this.handleClick(e, 'Option Four')} 
        className="aMenuButton" 
       >Option Four</button> 
       <button 
        label="Previous Menu" 
        onClick={() => this.setState({ Selected: MainMenu })} 
        className="aPrevButton" 
       >PREVIOUS MENU</button> 
      </div> 
     ); 

     const SetUpOptions =() => (
      <div> 
       <button 
        label="Option One" 
        onClick={(e) => this.handleClick(e, 'Option One')} 
        className="aMenuButton" 
       >Option One</button> 
       <button 
        label="Option Two" 
        onClick={(e) => this.handleClick(e, 'Option Two')} 
        className="aMenuButton" 
       >Option Two</button> 
       <button 
        label="Option Three" 
        onClick={(e) => this.handleClick(e, 'Option Three')} 
        className="aMenuButton" 
       >Option Three</button> 
       <button 
        label="Previous Menu" 
        onClick={() => this.setState({ Selected: MainMenu })} 
        className="aPrevButton" 
       >PREVIOUS MENU</button> 
      </div> 
     ); 

     const MoreOptions =() => (
      <div> 
       <button 
        label="Option One" 
        onClick={(e) => this.handleClick(e, 'Option One')} 
        className="aMenuButton" 
       >Option One</button> 
       <button 
        label="Option Two" 
        onClick={(e) => this.handleClick(e, 'Option Two')} 
        className="aMenuButton" 
       >Option Two</button> 
       <button 
        label="Option Three" 
        onClick={(e) => this.handleClick(e, 'Option Three')} 
        className="aMenuButton" 
       >Option Three</button> 
       <button 
        label="Option Four" 
        onClick={(e) => this.handleClick(e, 'Option Four')} 
        className="aMenuButton" 
       >Option Four</button> 
       <button 
        label="Previous Menu" 
        onClick={() => this.setState({ Selected: MainMenu })} 
        className="aPrevButton" 
       >PREVIOUS MENU</button> 
      </div> 
     ); 

     const { Selected } = this.state; 

     return (
      <div> 
       <div className="menuButtons"> 
        {Selected === 'MainMenu' ? <MainMenu /> : <Selected /> } 
       </div> 
      </div> 
     ) 
    } 
} 

Menu.propTypes = { 
    handleHelpChange: PropTypes.func, 
    name: PropTypes.string, 
    menuName: PropTypes.string 
} 


export default Menu; 
+1

我认为你的渲染功能在菜单中有一个错误。您不能只将字符串更改为React组件。如果Selected =“FileOptions”,则不能执行,并且期望它将会是。我不确定为什么它会呈现MainMenu,你可能想要检查从require('electron')返回的内容。remote.getGlobal('sharedObject')。hlpOne' – Yiou

+0

sharedObject呈现页面内容并且不会混淆菜单上。现在由于const {Selected} = this.state而呈现MainMenu或FileOptions。当单击一个菜单项时,状态将被更新并调用一个函数,导致组件重新渲染。整个菜单系统工作正常,它只是始终从MainMenu开始。希望能找到一种方法,从不同的菜单开始,如FileOptions – user3622460

react docs for componentWillMount

componentWillMount()被调用安装发生之前。 它在render()之前调用,因此在此方法中同步设置状态 不会触发重新渲染。避免在此方法中引入任何 副作用或订阅。这是在服务器渲染上调用的唯一的 生命周期钩子。通常,我们建议使用 ,而不是使用constructor()

更新1

设置在构造函数中所选的菜单名称和componentWillMount删除的setState。

更新2

@Yiou注意到<Selected />不是组件。

class Menu extends Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
     Selected: props.menuName || '', 
     name: '' 
     } 
    } 

    // .... 

    render() { 

    // after you created all your menu constant implement a switch to select 
    // which menu is going to render 
    const { Selected } = this.state; 
    let SelectedMenu; 
    switch(Selected) { 
     case 'MainMenu': 
     SelectedMenu = MainMenu; 
     break; 
     case 'FileOptions': 
     SelectedMenu = FileOptions; 
     break; 
     default: 
     SelectedMenu = MainMenu; 
     break; 
    } 

    return (
     <div> 
      <div className="menuButtons"> 
       {SelectedMenu()} 
      </div> 
     </div> 
    ) 
    }  
} 
+0

我不明白,我有构造函数集。如果我在构造函数中设置了Selected:this.props.menuName - 我得到了相同的结果。 – user3622460

+0

@ user3622460用一段代码更新了答案,它可能会帮助你 – bennygenel

+0

啊,这就是我在介绍componentWillMount之前所做的。不起作用。如果我将menuName设置为'FileOptions',菜单将无法加载。无论出于何种原因,如果我没有通过MainMenu,它将无法加载任何菜单。 – user3622460