使用 Baobab 影响多个组件的状态
State Affecting Multiple Components in React with Baobab
我正在将 HTML、CSS 和 jQuery 中制作的 90% 完整的网站翻译成更具前瞻性的 React "application"。我有一些非常基本的原则,我正在努力掌握这些原则——我真的很喜欢 React 的 JSX 语言,但也在努力处理我之前在 jQuery 中实现的繁重的 UI 操作。
为了让我习惯这些概念,我从我网站上最简单的交互之一开始——将鼠标悬停在菜单按钮上并部分显示侧边菜单(例如 20 像素)。我的组件结构如下:
var App = React.createClass({
render: function() {
return (
<div id="reactWrap">
<MainNav ref="main-nav"/>
<SideNav projects={PROJECTS} ref="side-nav" />
<RouteHandler projects={PROJECTS} ref="content" />
</div>
)
}
});
MainNav 包括 'hamburger' 按钮和站点标题:
render: function() {
return (
<nav className="fixed-nav">
<div id="menu-button" onMouseEnter={this.teaseMenu} onMouseLeave={this.unteaseMenu} ref="menu-btn">
<span className="menu-line"></span>
</div>
<span className="site-title">Lorem Ipsum</span>
</nav>
)
}
当“#menu-button”悬停时,我正在使用 "menuActions.isHovering()".
更改我在 "teaseMenu()" 内的 Baobab 中定义的状态树
....
teaseMenu: function(e) {
menuActions.isHovering();
// other stuff done
},....
我遇到的困难是,一旦更改在我的 stateTree 中受到影响,我就不确定如何将此更改的知识提供给依赖它的所有其他元素。例如,与 "MainNav" 完全无关并且它是 child "#menu-button" 的 SideNav 如何意识到这一变化并相应地改变它的状态?这可以简单地在 jQuery 中使用类似以下内容解决:
globalVars.menuBtn.on({
mouseenter: function(e) {
var self = $(this);
var movePercentage = (-100 + (20 / globalVars.sideNavW * 100))/2;
if (!pageStatus.menuActive) {
globalVars.wrap.addClass('menu-hover');
globalVars.sideNav.css({
'left': movePercentage + '%'
});
menuBtnIn(e, self);
}
},....
Flux 是执行此操作的好方法,我强烈建议您将其合并到您的网站中,因为它会使很多事情变得更容易。阅读此页面以获取更多信息:https://facebook.github.io/flux/docs/overview.html
但是,只要 SideNav
.
中发生某些事情,您也可以使用根 App
中的状态来影响 MainNav
上的变化
考虑对您的根应用程序组件进行此更改:
var App = React.createClass({
getInitialState: function() {
return {
sideNavShowSomething: false
}
},
mainNavChangeHandler: function(sideNavShowSomething) {
this.setState({
sideNavShowSomething: sideNavShowSomething
})
},
render: function() {
return (
<div id="reactWrap">
<MainNav ref="main-nav" onChange={this.mainNavChangeHandler} />
<SideNav projects={PROJECTS} ref="side-nav" showSomething={this.state.sideNavShowSomething} />
<RouteHandler projects={PROJECTS} ref="content" />
</div>
)
}
});
以上示例说明了如何使用根 App
的状态来影响其子项的更改。你的 MainNav
现在接受 onChange
的一个函数,它是一个函数。每当发生您想要通知根 App
的更改时,MainNav
就会调用此函数。在此示例中,mainNavChangeHandler
是使用布尔值 sideNavShowSomething
变量执行的。在你的情况下,你可能想做一些更复杂的事情;)
因此,当您在 MainNav
中调用 this.props.onChange(true)
时,您的根应用程序将更新它的状态,然后 SideNav
将接收 this.props.showSomething
作为 true wheras 之前它是 false .通过这样做,您可以通过利用对根的回调 App
并处理新的道具来影响子组件之间的变化。
我正在将 HTML、CSS 和 jQuery 中制作的 90% 完整的网站翻译成更具前瞻性的 React "application"。我有一些非常基本的原则,我正在努力掌握这些原则——我真的很喜欢 React 的 JSX 语言,但也在努力处理我之前在 jQuery 中实现的繁重的 UI 操作。
为了让我习惯这些概念,我从我网站上最简单的交互之一开始——将鼠标悬停在菜单按钮上并部分显示侧边菜单(例如 20 像素)。我的组件结构如下:
var App = React.createClass({
render: function() {
return (
<div id="reactWrap">
<MainNav ref="main-nav"/>
<SideNav projects={PROJECTS} ref="side-nav" />
<RouteHandler projects={PROJECTS} ref="content" />
</div>
)
}
});
MainNav 包括 'hamburger' 按钮和站点标题:
render: function() {
return (
<nav className="fixed-nav">
<div id="menu-button" onMouseEnter={this.teaseMenu} onMouseLeave={this.unteaseMenu} ref="menu-btn">
<span className="menu-line"></span>
</div>
<span className="site-title">Lorem Ipsum</span>
</nav>
)
}
当“#menu-button”悬停时,我正在使用 "menuActions.isHovering()".
更改我在 "teaseMenu()" 内的 Baobab 中定义的状态树....
teaseMenu: function(e) {
menuActions.isHovering();
// other stuff done
},....
我遇到的困难是,一旦更改在我的 stateTree 中受到影响,我就不确定如何将此更改的知识提供给依赖它的所有其他元素。例如,与 "MainNav" 完全无关并且它是 child "#menu-button" 的 SideNav 如何意识到这一变化并相应地改变它的状态?这可以简单地在 jQuery 中使用类似以下内容解决:
globalVars.menuBtn.on({
mouseenter: function(e) {
var self = $(this);
var movePercentage = (-100 + (20 / globalVars.sideNavW * 100))/2;
if (!pageStatus.menuActive) {
globalVars.wrap.addClass('menu-hover');
globalVars.sideNav.css({
'left': movePercentage + '%'
});
menuBtnIn(e, self);
}
},....
Flux 是执行此操作的好方法,我强烈建议您将其合并到您的网站中,因为它会使很多事情变得更容易。阅读此页面以获取更多信息:https://facebook.github.io/flux/docs/overview.html
但是,只要 SideNav
.
App
中的状态来影响 MainNav
上的变化
考虑对您的根应用程序组件进行此更改:
var App = React.createClass({
getInitialState: function() {
return {
sideNavShowSomething: false
}
},
mainNavChangeHandler: function(sideNavShowSomething) {
this.setState({
sideNavShowSomething: sideNavShowSomething
})
},
render: function() {
return (
<div id="reactWrap">
<MainNav ref="main-nav" onChange={this.mainNavChangeHandler} />
<SideNav projects={PROJECTS} ref="side-nav" showSomething={this.state.sideNavShowSomething} />
<RouteHandler projects={PROJECTS} ref="content" />
</div>
)
}
});
以上示例说明了如何使用根 App
的状态来影响其子项的更改。你的 MainNav
现在接受 onChange
的一个函数,它是一个函数。每当发生您想要通知根 App
的更改时,MainNav
就会调用此函数。在此示例中,mainNavChangeHandler
是使用布尔值 sideNavShowSomething
变量执行的。在你的情况下,你可能想做一些更复杂的事情;)
因此,当您在 MainNav
中调用 this.props.onChange(true)
时,您的根应用程序将更新它的状态,然后 SideNav
将接收 this.props.showSomething
作为 true wheras 之前它是 false .通过这样做,您可以通过利用对根的回调 App
并处理新的道具来影响子组件之间的变化。