2016-04-11 75 views
0

我对reactJS相当新颖,我想知道处理在单个页面上具有相同表单组件的最佳方法。请记住,我正在使用助焊剂,并且组件正在与商店交谈。在同一页面上使用相同的ReactJS表单组件

例如: < SearchForm /> < SearchForm />

当试图使用的形式#1的输入字段,形式#2的同时获取从形式#1的值。我认为问题来自商店。组件正在对同一商店说话,商店一次更新所有组件。

我该如何处理这个问题?

这是我到目前为止的代码。

const SearchField = React.createClass({ 

propTypes: { 
    isSearchActivated: React.PropTypes.bool.isRequired, 
}, 

_onChange() { 
    var previousHighlightedIndex = this.state.highlightedIndex; 
    this.setState(getStateFromStores(), function() { 
     if (previousHighlightedIndex == 0 && 
       this.state.highlightedIndex == -1) { 
      this.refs.SearchBar.selectAll(); 
     } 
    }); 
}, 

componentDidMount() { 
    if (window.location.pathname == "/" && !Modernizr.mq("screen only and (max-width: 768px)")) { 
     $(ReactDOM.findDOMNode(this.refs.SearchBar)).find("input").focus(); 
    } 
}, 

componentWillUnmount() { 
    SearchResultStore.removeChangeListener(this._onChange); 
}, 

onChangeSearchString(e) { 
    SearchResultsUtils.search(e.target.value); 
}, 

onBlur(e) { 
    var self = this; 
    var cb = function() { 
     if (!self.state.selectedResult && self.state.results.length) { 
      self.handleSelectedResult(0); 
     } 

     SearchResultsActions.disallowResultsDisplay(); 
    }; 
    if($(".search-bar").hasClass("active")) { 
     $(".search-bar.active").removeClass("active"); 
    } 
}, 

onFocus(e) { 
    $(ReactDOM.findDOMNode(this.refs.SearchBar)).closest(".search-bar").addClass("active"); 
}, 

handleSubmit() { 
    var self = this; 
}, 

render() { 
    var className = "search-bar clearfix"; 

    return (
     <div className={className}> 
      <div className="search-bar-search"> 
       <SearchBar 
        searchString={this.state.searchString} 
        onChange={this.onChangeSearchString} 
        onKeyDown={this.onKeyDownSearchString} 
        onFocus={this.onFocus} 
        onBlur={this.onBlur} 
        placeholder="Search Meds or Conditions" 
        ref="SearchBar" /> 
      </div> 

      <SearchButton 
       handleSubmit={this.handleSubmit} /> 
     </div> 
    ); 
}, 
}); 

module.exports = SearchField; 

感谢您的帮助提前。

+0

你可以添加你的代码吗?听起来就像两种形式共享相同的状态。 – tvdpol

+0

如果你确实有简单的'',那么当你输入表单#1中的内容时,反应不会导致表单#2被更新。你的标签也提到了jQuery。你有没有机会使用jQuery来更新表单?那么这更可能是你问题的根源。 (你真的不应该混合jQuery并以这种方式作出反应)。你能为你的问题增加更多的代码吗? – wintvelt

+0

我更新了问题。 – Hector

回答

0

阵营有状态的组件:

组件可以保持存储在(经由this.state访问)

它允许你有<SearchForm />#1value1,和<SearchForm />#2value2内部状态数据this.state

要建立表单,请选中:https://facebook.github.io/react/docs/forms.html

+0

你会如何设置它?你能给我一个示例代码片断吗? – Hector

+0

请参阅@WitVault答案这是greate:http://stackoverflow.com/questions/36552422/working-with-the-same-reactjs-form-component-on-the-same-page/36554606#36554606 – jibees

1

当然,您可以在您的应用程序中多次重复使用您的组件。

1.如果你不希望有任何状态:

在你的情况,你可以提供表单提交处理程序回调道具。如果您不想在搜索表单上保留任何状态。 如 对于表单1

<Searchform submitHandler={searchForm1Handler}/> 

对于表单2

<Searchform submitHandler={searchForm2Handler}/> 

和内部搜索表单组件

render(){ 
    return (
    <form id="searchform" onSubmit={this.props.submitHandler} role="form"> 
     // other input and buttons 
    </form> 
    ) 
} 

2.与各国

每一次这种方法合作mponent将拥有自己的独立状态,这对他们来说是私密的。

这里是样品成分说明这

import React ,{ Component } from 'react'; 

export default class SearchForm extends Component { 

    constructor(props){ 
     super(props); 
     this.state = { 
      searchTerm : '' 
     }; 
     this.submit = this.submit.bind(this); 
     this.changeSearchTerm = this.changeSearchTerm.bind(this); 
    } 

    submit(e){ 

     e.preventDefault(); 

     let searchTerm = this.state.searchTerm; 
     //Now perform some action based on search term you get 
    } 

    changeSearchTerm(e){ 
     this.setState({searchTerm :e.target.value}); 
    } 

    render(){ 

     return(
      <div> 
       <div className="row"> 
        <div className="col-md-12"> 
         <form role="form" className="form-horizontal" onSubmit={this.submit}> 
         <fieldset> 
          <div className="form-group"> 
          <div className="col-sm-6"> 
           <input id="st" type="text" placeholder="search term" onChange={this.changeSearchTerm} value={this.state.searchTerm} required autofocus/> 
          </div> 
         </div> 
         <div className="form-group"> 
          <div className="col-xs-12 text-center"> 
           <button className="btn"> 
           Search 
           </button> 
          </div> 
          </div> 
         </fieldset> 
         </form> 
        </div> 
       </div> 
      </div> 
     ) 
    } 
} 

现在使用它们

对于表单1

<Searchform/> 

对于表单2

<Searchform/> 
0

它看起来像你的存储onl y为一个表单保存一个状态 - 其中包括搜索值。
如果您渲染此表单两次,那么这两个表单在每次更改时检索相同的状态。所以它们是按设计彼此完全相同的副本。如果一个表单发生更改,则两个表单都会注意到更改,并且这两个表单都会从存储中检索完全相同的状态。

为了解决这个问题,我建议:

  • 变化的存储,以便它可以给每个窗体
  • 通过这个ID保存状态多种形式,每一个都有自己的ID为道具,例如<SearchForm formID='form1'/> <SearchForm formID='form2'/>
  • 通过formID下为道具,以表格的所有儿童,如<SearchField>
  • <SearchField>内,请确保您的组件只能从自身的formID呈现的状态。您可能需要更新getStateFromStores()方法本身。或者在<SearchField>里面先过滤掉相关的东西,然后把它传递给setState()
  • 当你的组件通知商店有什么变化(我想这是SearchResultsUtils.search(e.target.value);做的),那么你也需要通过formID。所以商店会知道更新哪种形式。

PS:我觉得你的代码是缺少一些线componentDidMount():你的代码删除监听器来存储的变化,但你的代码中添加监听器丢失。您的组件中缺少调用_onChange()方法的代码。

相关问题