在同一页面上使用相同的ReactJS表单组件

时间:2016-04-11 15:04:25

标签: javascript jquery reactjs jsx

我对reactJS相当新,我想知道在单个页面上处理相同表单组件的最佳方法是什么。请记住,我正在使用flux,组件正在与商店交谈。

例如:     < 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;

感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

您肯定可以在应用程序中多次重复使用组件。

1.如果您不想拥有任何州:

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

#set working directory
require(leaflet)
require(dplyr)

#Build data.frame with 10 obs + 3 cols
power <- data.frame(Latitude <-c(33.515556, 38.060556, 47.903056, 49.71, 49.041667, 31.934167, 54.140586, 54.140586, 48.494444, 48.494444), Longitude <- c(
129.837222, -77.789444, 7.563056, 8.415278, 9.175, -82.343889, 13.664422, 13.664422, 17.681944, 17.681944), start <- c(as.Date(
"15-Sep-1971", "1-Dec-1971", "1-Feb-1972", "1-Feb-1972", "1-Feb-1972", "1-Feb-1972", "1-Apr-1972", "1-Apr-1972", "24-Apr-1972", "24-Apr-1972", format = "%d-%b-%Y")))

#"Dynamic" leaflet Fails1: While+For combo
i<- as.Date("1971-09-14")
while (i < as.Date("1972-05-01")) {    for(star in start){
if (star > i) {
leaflet(power) %>% addTiles() %>%
  addCircleMarkers(lng = ~Longitude, lat = ~Latitude)
}}
i <- i+60}

#"Dynamic" leaflet Fails2: For+break combo
lap <- seq(as.Date("1971-09-14"), as.Date("1972-05-01"), by = "month")
for(i in lap) {
leaflet (data = power[power$start > i,]) %>%
addTiles() %>%
addCircleMarkers(lng = ~Longitude, lat = ~Latitude)  
if (i > as.Date("1951-01-01")) 
{      break }}

表格2

<Searchform submitHandler={searchForm1Handler}/>

并在搜索表单组件中

<Searchform submitHandler={searchForm2Handler}/> 

<强> 2。状态

使用这种方法,每个组件都有自己独立的状态,这些状态对他们来说是私有的。

以下是说明此内容的示例组件

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

现在使用它们

表格1

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>
        )
    }
}

表格2

<Searchform/>

答案 1 :(得分:0)

React有状态组件:

  

组件可以维护内部状态数据(通过this.state访问)

允许您<SearchForm />#1 value1 <SearchForm />#2 value2 this.state存储在auto func = [&params]( auto const& x , auto& dxdt , double t ) { sys( x , dxdt , t , &params ); }; rk.do_step(my_fun, inout, t, dt);

要构建表单,请查看:https://facebook.github.io/react/docs/forms.html

答案 2 :(得分:0)

看起来您的商店只为一个表单保存一个州 - 其中包括搜索值 如果您将此表单呈现两次,则两个表单在每次更改时都会检索相同的状态。因此,它们是设计上彼此的精确副本。如果一个表单发生更改,则两个表单都会注意到更改,两个表单都将从商店中检索完全相同的状态。

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

  • 更改商店,以便它可以保存多个表单的状态,每个表单都有自己的ID
  • 将此ID作为道具传递给每个表格,例如<SearchForm formID='form1'/> <SearchForm formID='form2'/>
  • formID作为道具传递给表单中的所有子项,例如<SearchField>
  • <SearchField>内,确保您的组件仅从自己的formID呈现状态。您可能需要更新getStateFromStores()方法本身。或者在<SearchField>内部首先过滤相关内容,然后再将其传递给setState()
  • 当您的组件通知商店某些内容已发生变化时(我猜这是SearchResultsUtils.search(e.target.value);所做的),那么您还需要传递formID。因此商店将知道要更新的表格。

PS:我认为你的代码缺少componentDidMount()中的某些行:你有代码删除监听器以存储更改,但是缺少添加监听器的代码。您的组件中缺少调用_onChange()方法的代码。