如何在我的组件首次渲染时更新我的菜单状态?
我有一个用参数调用的应用程序。现在,我的菜单总是加载到默认的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;
从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>
)
}
}
我不明白,我有构造函数集。如果我在构造函数中设置了Selected:this.props.menuName - 我得到了相同的结果。 – user3622460
@ user3622460用一段代码更新了答案,它可能会帮助你 – bennygenel
啊,这就是我在介绍componentWillMount之前所做的。不起作用。如果我将menuName设置为'FileOptions',菜单将无法加载。无论出于何种原因,如果我没有通过MainMenu,它将无法加载任何菜单。 – user3622460
我认为你的渲染功能在菜单中有一个错误。您不能只将字符串更改为React组件。如果Selected =“FileOptions”,则不能执行 ,并且期望它将会是 。我不确定为什么它会呈现MainMenu,你可能想要检查从require('electron')返回的内容。remote.getGlobal('sharedObject')。hlpOne' –
Yiou
sharedObject呈现页面内容并且不会混淆菜单上。现在 由于const {Selected} = this.state而呈现MainMenu或FileOptions。当单击一个菜单项时,状态将被更新并调用一个函数,导致组件重新渲染。整个菜单系统工作正常,它只是始终从MainMenu开始。希望能找到一种方法,从不同的菜单开始,如FileOptions –
user3622460