99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

第九步:Footer和Navbar組件

2021-10-23 14:32 更新

第九步:Footer和Navbar組件

Navbar和Footer都是相對簡單的組件。Footer組件獲取并展示Top5人物角色,Navbar組件獲取并展示所有角色數(shù)量,然后還初始化一個Socket.IO事件監(jiān)聽器,用以跟蹤在線訪客的數(shù)量。

注意:這一節(jié)會比別的小節(jié)要稍長些,因?yàn)槲視谶@里談到一些新概念,而其它小節(jié)將基于它們進(jìn)行開發(fā)。

Footer組件

在components目錄下新建文件Footer.js

import React from 'react';
import {Link} from 'react-router';
import FooterStore from '../stores/FooterStore'
import FooterActions from '../actions/FooterActions';

class Footer extends React.Component {
  constructor(props) {
    super(props);
    this.state = FooterStore.getState();
    this.onChange = this.onChange.bind(this);
  }

  componentDidMount() {
    FooterStore.listen(this.onChange);
    FooterActions.getTopCharacters();
  }

  componentWillUnmount() {
    FooterStore.unlisten(this.onChange);
  }

  onChange(state) {
    this.setState(state);
  }

  render() {
    let leaderboardCharacters = this.state.characters.map((character) => {
      return (
        <li key={character.characterId}>
          <Link to={'/characters/' + character.characterId}>
            <img className='thumb-md' src={'http://image.eveonline.com/Character/' + character.characterId + '_128.jpg'} />
          </Link>
        </li>
      )
    });

    return (
      <footer>
        <div className='container'>
          <div className='row'>
            <div className='col-sm-5'>
              <h3 className='lead'><strong>Information</strong> and <strong>Copyright</strong></h3>
              <p>Powered by <strong>Node.js</strong>, <strong>MongoDB</strong> and <strong>React</strong> with Flux architecture and server-side rendering.</p>
              <p>You may view the <a href='http://www.15014759268.cn/targetlink?url=https://github.com/sahat/newedenfaces-react'>Source Code</a> behind this project on GitHub.</p>
              <p>? 2015 Sahat Yalkabov.</p>
            </div>
            <div className='col-sm-7 hidden-xs'>
              <h3 className='lead'><strong>Leaderboard</strong> Top 5 Characters</h3>
              <ul className='list-inline'>
                {leaderboardCharacters}
              </ul>
            </div>
          </div>
        </div>
      </footer>
    );
  }
}

export default Footer;

為防止你還未熟悉ES6語法而暈頭轉(zhuǎn)向,在這里我將最后一次展示這段代碼用ES5是如何寫的,另外你也可以參看Using Alt with ES5指南來了解創(chuàng)建action和store時語法的不同。

var React = require('react');
var Link = require('react-router').Link;
var FooterStore = require('../stores/FooterStore');
var FooterActions = require('../actions/FooterActions');

var Footer = React.createClass({
  getInitialState: function() {
    return FooterStore.getState();
  }

  componentDidMount: function() {
    FooterStore.listen(this.onChange);
    FooterActions.getTopCharacters();
  }

  componentWillUnmount: function() {
    FooterStore.unlisten(this.onChange);
  }

  onChange: function(state) {
    this.setState(state);
  }

  render() {
    var leaderboardCharacters = this.state.characters.map(function(character) {
      return (
        <li key={character.characterId}>
          <Link to={'/characters/' + character.characterId}>
            <img className='thumb-md' src={'http://image.eveonline.com/Character/' + character.characterId + '_128.jpg'} />
          </Link>
        </li>
      );
    });

    return (
      <footer>
        <div className='container'>
          <div className='row'>
            <div className='col-sm-5'>
              <h3 className='lead'><strong>Information</strong> and <strong>Copyright</strong></h3>
              <p>Powered by <strong>Node.js</strong>, <strong>MongoDB</strong> and <strong>React</strong> with Flux architecture and server-side rendering.</p>
              <p>You may view the <a href='http://www.15014759268.cn/targetlink?url=https://github.com/sahat/newedenfaces-react'>Source Code</a> behind this project on GitHub.</p>
              <p>? 2015 Sahat Yalkabov.</p>
            </div>
            <div className='col-sm-7 hidden-xs'>
              <h3 className='lead'><strong>Leaderboard</strong> Top 5 Characters</h3>
              <ul className='list-inline'>
                {leaderboardCharacters}
              </ul>
            </div>
          </div>
        </div>
      </footer>
    );
  }
});

module.exports = Footer;

如果你還記得Flux架構(gòu)那一節(jié)的內(nèi)容,這些代碼看上去應(yīng)該挺熟悉。當(dāng)組件加載后,將初始組件狀態(tài)設(shè)置為FooterStore中的值,然后初始化store監(jiān)聽器。同樣,當(dāng)組件被卸載(比如導(dǎo)航至另一頁面),store監(jiān)聽器也被移除。當(dāng)store更新,onChange函數(shù)被調(diào)用,然后反過來又更新Footer的狀態(tài)。

如果你之前用過React,在這里你需要注意的是,當(dāng)使用ES6 class創(chuàng)建React組件,組件方法不再自動綁定this。也就是說,當(dāng)你調(diào)用組件內(nèi)部方法時,你需要手動綁定this,在之前,React.createClass()會幫我們自動綁定:

自動綁定:當(dāng)在JavaScript中創(chuàng)建回調(diào)時,你經(jīng)常需要手動綁定方法到它的實(shí)例以保證this的值正確,使用React,所有方法都自動綁定到組件實(shí)例。

以上出自于官方文檔。不過在ES6中我們要這么做:

this.onChange = this.onChange.bind(this);

下面是關(guān)于這個問題更詳細(xì)的例子:

class App extends React.Component {

  constructor(props) {
    super(props);
    this.state = AppStore.getState();
    this.onChange = this.onChange; // Need to add `.bind(this)`.
  }

  onChange(state) {
    // Object `this` will be undefined without binding it explicitly.
    this.setState(state);
  }

  render() {
    return null;
  }
}

現(xiàn)在你需要了解JavaScript中的map()方法,即使你之前用過,也還是可能搞不清楚它在JSX中是怎么用的(React官方教程并沒有很好的解釋它)。

它基本上是一個for-each循環(huán),和Jade和Handlebars中的類似,但在這里你可以將結(jié)果分配給一個變量,然后你就可以在JSX里使用它了,就和用其它變量一樣。它在React中很常見,你會經(jīng)常用到。

注意:當(dāng)渲染動態(tài)子組件時,如上面的leaderboardCharacters,React會要求你使用key屬性來指定每一個子組件。

Link組件當(dāng)指定合適的href屬性時會渲染一個鏈接標(biāo)簽,它還知道鏈接的目標(biāo)是否可用,從而給鏈接加上active的類。如果你使用React Router,你需要使用Link模塊在應(yīng)用內(nèi)部進(jìn)行導(dǎo)航。

Actions

下面,我們將為Footer組件創(chuàng)建action和store,在app/actions目錄新建FooterActions.js并添加:

import alt from '../alt';

class FooterActions {
  constructor() {
    this.generateActions(
      'getTopCharactersSuccess',
      'getTopCharactersFail'
    );
  }

  getTopCharacters() {
    $.ajax({ url: '/api/characters/top' })
      .done((data) => {
        this.actions.getTopCharactersSuccess(data)
      })
      .fail((jqXhr) => {
        this.actions.getTopCharactersFail(jqXhr)
      });
  }
}

export default alt.createActions(FooterActions);

首先,注意我們從第七步創(chuàng)建的alt.js中導(dǎo)入了一個Alt的實(shí)例,而不是從我們安裝的Alt模塊中。它是一個Alt的實(shí)例,實(shí)現(xiàn)了Flux dispatcher并提供創(chuàng)建Alt action和store的方法。你可以把它想象為我們的store和action之間的膠水。

這里我們有3個action,一個使用ajax獲取數(shù)據(jù),另外兩個用來通知store獲取數(shù)據(jù)是成功還是失敗。在這個例子里,知道getTopCharacters何時被觸發(fā)并沒有什么用,我們真正想知道的是action執(zhí)行成功(更新store然后重新渲染組件)還是失?。@示一個錯誤通知)。

Action可以很復(fù)雜,也可以很簡單。有些action我們不關(guān)心它們做了什么,我們只關(guān)心它們是否被觸發(fā),比如這里的ajaxInProgressajaxComplete被用來通知store,AJAX請求是正在進(jìn)行還是已經(jīng)完成。

注意:Alt的action能通過generateActions方法創(chuàng)建,只要它們直接通向dispatch。具體可參看官方文檔。

下面的兩種創(chuàng)建action方式是等價的,可依據(jù)你的喜好進(jìn)行選擇:

getTopCharactersSuccess(payload) {
  this.dispatch(payload);
}

getTopCharactersFail(payload) {
  this.dispatch(payload);
}

// Equivalent to this...
this.generateActions(
  'getTopCharactersSuccess',
  'getTopCharactersFail'
);

最后,我們通過alt.createActions將FooterActions封裝并暴露出來,然后我們可以在Footer組件里導(dǎo)入并使用它。

Store

下面,在app/stores目錄下新建文件FooterStore.js

import alt from '../alt';
import FooterActions from '../actions/FooterActions';

class FooterStore {
  constructor() {
    this.bindActions(FooterActions);
    this.characters = [];
  }

  onGetTopCharactersSuccess(data) {
    this.characters = data.slice(0, 5);
  }

  onGetTopCharactersFail(jqXhr) {
    // Handle multiple response formats, fallback to HTTP status code number.
    toastr.error(jqXhr.responseJSON && jqXhr.responseJSON.message || jqXhr.responseText || jqXhr.statusText);
  }
}

export default alt.createStore(FooterStore);

在store中創(chuàng)建的變量,比如this所賦值的變量,都將成為狀態(tài)的一部分。當(dāng)Footer組件初始化并調(diào)用FooterStore.getState(),它會獲取在構(gòu)造函數(shù)中指定的當(dāng)前狀態(tài)(在一開始只是一個空數(shù)組,而遍歷空數(shù)組會返回另一個空數(shù)組,所以在Footer組件第一次加載時并沒有渲染任何內(nèi)容)。

bindActions用于將action綁定到store中定義的相應(yīng)處理函數(shù)。比如,一個命名為foo的action會匹配store中叫做onFoo或者foo的處理函數(shù),不過需要注意它不會同時匹配兩者。因此我們在FooterActions.js中定義的actiongetTopCharactersSuccessgetTopCharactersFail會匹配到這里的處理函數(shù)onGetTopCharactersSuccessonGetTopCharactersFail。

注意:如需更精細(xì)的控制store監(jiān)聽的action以及它們綁定的處理函數(shù),可參看文檔中的bindListeners方法。

onGetTopCharactersSuccess處理函數(shù)中我們更新了store的數(shù)據(jù),現(xiàn)在它包含Top 5角色,并且我們在Footer組件中初始化了store監(jiān)聽器,當(dāng)FooterStore更新后組件會自動的重新渲染。

我們會使用Toastr庫來處理通知。也許你會問為什么不使用純React通知組件呢?也許你以前看到過為React設(shè)計的通知組件,但我個人認(rèn)為這是少數(shù)不太適合用React的地方(還有一個是tooltips)。我認(rèn)為要從應(yīng)用的任何地方顯示一個通知,使用命令方式遠(yuǎn)比聲明式要簡單,我以前曾經(jīng)構(gòu)建過使用React和Flux的通知組件,但老實(shí)說,用來它處理顯隱狀態(tài)、動畫以及z-index位置等,非常痛苦。

打開app/components下的App.js并導(dǎo)入Footer組件:

import Footer from './Footer';

然后將<Footer />添加到<RouterHandler / >組件后面:

<div>
  <RouteHandler />
  <Footer />
</div>

刷新瀏覽器你應(yīng)該看到新的底部:

我們稍后會實(shí)現(xiàn)Express API以及添加人物角色數(shù)據(jù)庫,不過現(xiàn)在讓我們還是繼續(xù)構(gòu)建Navbar組件。因?yàn)橹耙呀?jīng)講過了alt action和store,這里將會盡量簡略的說明Navbar組件如何構(gòu)建。

Navbar組件

在app/components目錄新建文件Navbar.js

import React from 'react';
import {Link} from 'react-router';
import NavbarStore from '../stores/NavbarStore';
import NavbarActions from '../actions/NavbarActions';

class Navbar extends React.Component {
  constructor(props) {
    super(props);
    this.state = NavbarStore.getState();
    this.onChange = this.onChange.bind(this);
  }

  componentDidMount() {
    NavbarStore.listen(this.onChange);
    NavbarActions.getCharacterCount();

    let socket = io.connect();

    socket.on('onlineUsers', (data) => {
      NavbarActions.updateOnlineUsers(data);
    });

    $(document).ajaxStart(() => {
      NavbarActions.updateAjaxAnimation('fadeIn');
    });

    $(document).ajaxComplete(() => {
      setTimeout(() => {
        NavbarActions.updateAjaxAnimation('fadeOut');
      }, 750);
    });
  }

  componentWillUnmount() {
    NavbarStore.unlisten(this.onChange);
  }

  onChange(state) {
    this.setState(state);
  }

  handleSubmit(event) {
    event.preventDefault();

    let searchQuery = this.state.searchQuery.trim();

    if (searchQuery) {
      NavbarActions.findCharacter({
        searchQuery: searchQuery,
        searchForm: this.refs.searchForm.getDOMNode(),
        router: this.context.router
      });
    }
  }

  render() {
    return (
      <nav className='navbar navbar-default navbar-static-top'>
        <div className='navbar-header'>
          <button type='button' className='navbar-toggle collapsed' data-toggle='collapse' data-target='#navbar'>
            <span className='sr-only'>Toggle navigation</span>
            <span className='icon-bar'></span>
            <span className='icon-bar'></span>
            <span className='icon-bar'></span>
          </button>
          <Link to='/' className='navbar-brand'>
            <span ref='triangles' className={'triangles animated ' + this.state.ajaxAnimationClass}>
              <div className='tri invert'></div>
              <div className='tri invert'></div>
              <div className='tri'></div>
              <div className='tri invert'></div>
              <div className='tri invert'></div>
              <div className='tri'></div>
              <div className='tri invert'></div>
              <div className='tri'></div>
              <div className='tri invert'></div>
            </span>
            NEF
            <span className='badge badge-up badge-danger'>{this.state.onlineUsers}</span>
          </Link>
        </div>
        <div id='navbar' className='navbar-collapse collapse'>
          <form ref='searchForm' className='navbar-form navbar-left animated' onSubmit={this.handleSubmit.bind(this)}>
            <div className='input-group'>
              <input type='text' className='form-control' placeholder={this.state.totalCharacters + ' characters'} value={this.state.searchQuery} onChange={NavbarActions.updateSearchQuery} />
              <span className='input-group-btn'>
                <button className='btn btn-default' onClick={this.handleSubmit.bind(this)}><span className='glyphicon glyphicon-search'></span></button>
              </span>
            </div>
          </form>
          <ul className='nav navbar-nav'>
            <li><Link to='/'>Home</Link></li>
            <li><Link to='/stats'>Stats</Link></li>
            <li className='dropdown'>
              <a href='#' className='dropdown-toggle' data-toggle='dropdown'>Top 100 <span className='caret'></span></a>
              <ul className='dropdown-menu'>
                <li><Link to='/top'>Top Overall</Link></li>
                <li className='dropdown-submenu'>
                  <Link to='/top/caldari'>Caldari</Link>
                  <ul className='dropdown-menu'>
                    <li><Link to='/top/caldari/achura'>Achura</Link></li>
                    <li><Link to='/top/caldari/civire'>Civire</Link></li>
                    <li><Link to='/top/caldari/deteis'>Deteis</Link></li>
                  </ul>
                </li>
                <li className='dropdown-submenu'>
                  <Link to='/top/gallente'>Gallente</Link>
                  <ul className='dropdown-menu'>
                    <li><Link to='/top/gallente/gallente'>Gallente</Link></li>
                    <li><Link to='/top/gallente/intaki'>Intaki</Link></li>
                    <li><Link to='/top/gallente/jin-mei'>Jin-Mei</Link></li>
                  </ul>
                </li>
                <li className='dropdown-submenu'>
                  <Link to='/top/minmatar'>Minmatar</Link>
                  <ul className='dropdown-menu'>
                    <li><Link to='/top/minmatar/brutor'>Brutor</Link></li>
                    <li><Link to='/top/minmatar/sebiestor'>Sebiestor</Link></li>
                    <li><Link to='/top/minmatar/vherokior'>Vherokior</Link></li>
                  </ul>
                </li>
                <li className='dropdown-submenu'>
                  <Link to='/top/amarr'>Amarr</Link>
                  <ul className='dropdown-menu'>
                    <li><Link to='/top/amarr/amarr'>Amarr</Link></li>
                    <li><Link to='/top/amarr/ni-kunni'>Ni-Kunni</Link></li>
                    <li><Link to='/top/amarr/khanid'>Khanid</Link></li>
                  </ul>
                </li>
                <li className='divider'></li>
                <li><Link to='/shame'>Hall of Shame</Link></li>
              </ul>
            </li>
            <li className='dropdown'>
              <a href='#' className='dropdown-toggle' data-toggle='dropdown'>Female <span className='caret'></span></a>
              <ul className='dropdown-menu'>
                <li><Link to='/female'>All</Link></li>
                <li className='dropdown-submenu'>
                  <Link to='/female/caldari'>Caldari</Link>
                  <ul className='dropdown-menu'>
                    <li><Link to='/female/caldari/achura'>Achura</Link></li>
                    <li><Link to='/female/caldari/civire/'>Civire</Link></li>
                    <li><Link to='/female/caldari/deteis'>Deteis</Link></li>
                  </ul>
                </li>
                <li className='dropdown-submenu'>
                  <Link to='/female/gallente'>Gallente</Link>
                  <ul className='dropdown-menu'>
                    <li><Link to='/female/gallente/gallente'>Gallente</Link></li>
                    <li><Link to='/female/gallente/intaki'>Intaki</Link></li>
                    <li><Link to='/female/gallente/jin-mei'>Jin-Mei</Link></li>
                  </ul>
                </li>
                <li className='dropdown-submenu'>
                  <Link to='/female/minmatar'>Minmatar</Link>
                  <ul className='dropdown-menu'>
                    <li><Link to='/female/minmatar/brutor'>Brutor</Link></li>
                    <li><Link to='/female/minmatar/sebiestor'>Sebiestor</Link></li>
                    <li><Link to='/female/minmatar/vherokior'>Vherokior</Link></li>
                  </ul>
                </li>
                <li className='dropdown-submenu'>
                  <Link to='/female/amarr'>Amarr</Link>
                  <ul className='dropdown-menu'>
                    <li><Link to='/female/amarr/amarr'>Amarr</Link></li>
                    <li><Link to='/female/amarr/ni-kunni'>Ni-Kunni</Link></li>
                    <li><Link to='/female/amarr/khanid'>Khanid</Link></li>
                  </ul>
                </li>
              </ul>
            </li>
            <li className='dropdown'>
              <a href='#' className='dropdown-toggle' data-toggle='dropdown'>Male <span className='caret'></span></a>
              <ul className='dropdown-menu'>
                <li><Link to='/male'>All</Link></li>
                <li className='dropdown-submenu'>
                  <Link to='/male/caldari'>Caldari</Link>
                  <ul className='dropdown-menu'>
                    <li><Link to='/male/caldari/achura'>Achura</Link></li>
                    <li><Link to='/male/caldari/civire'>Civire</Link></li>
                    <li><Link to='/male/caldari/deteis'>Deteis</Link></li>
                  </ul>
                </li>
                <li className='dropdown-submenu'>
                  <Link to='/male/gallente'>Gallente</Link>
                  <ul className='dropdown-menu'>
                    <li><Link to='/male/gallente/gallente'>Gallente</Link></li>
                    <li><Link to='/male/gallente/intaki'>Intaki</Link></li>
                    <li><Link to='/male/gallente/jin-mei'>Jin-Mei</Link></li>
                  </ul>
                </li>
                <li className='dropdown-submenu'>
                  <Link to='/male/minmatar'>Minmatar</Link>
                  <ul className='dropdown-menu'>
                    <li><Link to='/male/minmatar/brutor'>Brutor</Link></li>
                    <li><Link to='/male/minmatar/sebiestor'>Sebiestor</Link></li>
                    <li><Link to='/male/minmatar/vherokior'>Vherokior</Link></li>
                  </ul>
                </li>
                <li className='dropdown-submenu'>
                  <Link to='/male/amarr'>Amarr</Link>
                  <ul className='dropdown-menu'>
                    <li><Link to='/male/amarr/amarr'>Amarr</Link></li>
                    <li><Link to='/male/amarr/ni-kunni'>Ni-Kunni</Link></li>
                    <li><Link to='/male/amarr/khanid'>Khanid</Link></li>
                  </ul>
                </li>
              </ul>
            </li>
            <li><Link to='/add'>Add</Link></li>
          </ul>
        </div>
      </nav>
    );
  }
}

Navbar.contextTypes = {
  router: React.PropTypes.func.isRequired
};

export default Navbar;

必須承認(rèn),這里使用循環(huán)的話可以少寫一些代碼,但現(xiàn)在這樣對我來說更直觀。

你可能立刻注意到的一個東西是class變量contextTypes。我們需要它來引用router的實(shí)例,從而讓我們能訪問當(dāng)前路徑、請求參數(shù)、路由參數(shù)以及到其它路由的變換。我們不在Navbar組件里直接使用它,而是將它作為一個參數(shù)傳遞給Navbar action,以使它能導(dǎo)航到特定character資料頁面。

componentDidMount是我們發(fā)起與Socket.IO的連接,并初始化ajaxStartajaxComplete時間監(jiān)聽器地方,我們會在AJAX請求時在NEF logo旁邊顯示加載指示。

handleSubmit是用來處理表單提交的程序,在按下Enter鍵或點(diǎn)擊Search圖標(biāo)時執(zhí)行。它會做一些輸入清理和驗(yàn)證工作,然后觸發(fā)findCharacter action。另外我們還傳遞了搜索區(qū)域的DOM節(jié)點(diǎn)給action,以便當(dāng)搜索結(jié)果為0時加載一個震動動畫。

Actions

在app/actions目錄下新建文件NavbarActions.js

import alt from '../alt';
import {assign} from 'underscore';

class NavbarActions {
  constructor() {
    this.generateActions(
      'updateOnlineUsers',
      'updateAjaxAnimation',
      'updateSearchQuery',
      'getCharacterCountSuccess',
      'getCharacterCountFail',
      'findCharacterSuccess',
      'findCharacterFail'
    );
  }

  findCharacter(payload) {
    $.ajax({
      url: '/api/characters/search',
      data: { name: payload.searchQuery }
    })
      .done((data) => {
        assign(payload, data);
        this.actions.findCharacterSuccess(payload);
      })
      .fail(() => {
        this.actions.findCharacterFail(payload);
      });
  }

  getCharacterCount() {
    $.ajax({ url: '/api/characters/count' })
      .done((data) => {
        this.actions.getCharacterCountSuccess(data)
      })
      .fail((jqXhr) => {
        this.actions.getCharacterCountFail(jqXhr)
      });
  }
}

export default alt.createActions(NavbarActions);

我想大多數(shù)action的命名應(yīng)該能夠自我解釋,不過為了更清楚的理解,在下面簡單的描述一下它們是干什么的:

Action Description
updateOnlineUsers 當(dāng)Socket.IO事件更新時設(shè)置在線用戶數(shù)
updateAjaxAnimation 添加”fadeIn”或”fadeOut”類到加載指示器
updateSearchQuery 當(dāng)使用鍵盤時設(shè)置搜索請求
getCharacterCount 從服務(wù)器獲取總角色數(shù)
getCharacterCountSuccess 返回角色總數(shù)
getCharacterCountFail 返回jQuery jqXhr對象
findCharacter 根據(jù)名稱查找角色

Store

在app/stores目錄下創(chuàng)建NavbarStore.js

import alt from '../alt';
import NavbarActions from '../actions/NavbarActions';

class NavbarStore {
  constructor() {
    this.bindActions(NavbarActions);
    this.totalCharacters = 0;
    this.onlineUsers = 0;
    this.searchQuery = '';
    this.ajaxAnimationClass = '';
  }

  onFindCharacterSuccess(payload) {
    payload.router.transitionTo('/characters/' + payload.characterId);
  }

  onFindCharacterFail(payload) {
    payload.searchForm.classList.add('shake');
    setTimeout(() => {
      payload.searchForm.classList.remove('shake');
    }, 1000);
  }

  onUpdateOnlineUsers(data) {
    this.onlineUsers = data.onlineUsers;
  }

  onUpdateAjaxAnimation(className) {
    this.ajaxAnimationClass = className; //fadein or fadeout
  }

  onUpdateSearchQuery(event) {
    this.searchQuery = event.target.value;
  }

  onGetCharacterCountSuccess(data) {
    this.totalCharacters = data.count;
  }

  onGetCharacterCountFail(jqXhr) {
    toastr.error(jqXhr.responseJSON.message);
  }
}

export default alt.createStore(NavbarStore);

回憶一下我們在Navbar組件中的代碼:

<input type='text' className='form-control' placeholder={this.state.totalCharacters + ' characters'} value={this.state.searchQuery} onChange={NavbarActions.updateSearchQuery} />

因?yàn)?a rel="external nofollow" target="_blank" target="_blank">onChange方法返回一個event對象,所以這里我們在onUpdateSearchQuery使用event.target.value來獲取輸入框的值。

再次打開App.js并導(dǎo)入Navbar組件:

import Navbar from './Navbar';

然后在<RouterHandler />添加<Navbar />組件:

<div>
  <Navbar />
  <RouteHandler />
  <Footer />
</div>

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號