影响Baobab React中多个组件的状态

State Affecting Multiple Components in React with Baobab

本文关键字:组件 状态 Baobab React 影响      更新时间:2023-09-26

我正在把一个用HTML、CSS和jQuery制作的90%完整的网站翻译成一个更具前瞻性思维的react "应用程序"。我有一些非常基本的原则,我正在努力掌握——我真的很喜欢react的JSX语言,但是很难处理我以前在jQuery中实现的大量UI操作。

为了让我习惯这些概念,我从我的网站上最简单的交互之一开始-将鼠标悬停在菜单按钮上,并将侧边菜单部分(例如20px)带出来。我的组件结构如下:

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 . ishover()"改变我在Baobab中定义的状态树。

....
teaseMenu: function(e) {
    menuActions.isHovering();
    // other stuff done
},....

我所挣扎的是,一旦更改在我的stateTree中受到影响,我不确定如何将此更改的知识提供给依赖它的所有其他元素。例如,与"MainNav"和它的子"#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

然而,你也可以使用根App的状态来影响MainNav的变化,无论SideNav发生了什么。

考虑对你的根应用组件做如下修改:

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为真,而以前它是假的。通过这样做,你可以通过使用对根App的回调来影响子组件之间的变化,并处理新的props来从它们中获得子组件。