如何使用React重新呈现搜索结果

时间:2018-04-05 12:06:49

标签: reactjs react-router

所以,我有一个Web应用程序,其中一个搜索栏嵌入到全局导航栏中。我希望能够在初始搜索后更新搜索栏中的输入字段并重新呈现搜索结果。

我尝试过多种方法,包括react-router重定向和componentWillReceiveProps(),听取浏览器更改等等。

以下是我的代码。关于如何解决的任何想法?

class SearchBox extends ComponentBase {

  constructor(props) {
  super(props);

 this.state = {
  dropdownOpen: false,
  location: '',
  term: '',
  distance: '50 mi',
  submitted: false,
  results: {}
 };

this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.select = this.select.bind(this);
this.toggle = this.toggle.bind(this);
}

componentDidMount() {
 this.setState({
  location: this.props.city
 });  
}

toggle(e) {
  this.setState({
      dropdownOpen: !this.state.dropdownOpen
  });
}

select(event) {
  //let d = event.target.innerText.replace(" mi", "");
  this.setState({
      dropdownOpen: !this.state.dropdownOpen,
      distance: d
  });
}

handleChange(e) {
  const {
      name, value
  } = e.target;
  this.setState({
      [name]: value
  });
}

handleSubmit(e) {
  e.preventDefault();
  this.setState({
      submitted: true
  });
  const {
      location, term, distance
  } = this.state;
  const {
      dispatch
  } = this.props;

  if (term && location) {
    let q = "?term=" + term + "&location=" + location + "&distance=" + distance;
    history.push("/results" + q);
   }
}

render() {
   const {
      location, term, distance
  } = this.state;

  return ( < form className = "form-inline" >
      < Input 
      type = "text"
      name = "term"
      id = "query"
      onChange = {
          this.handleChange
      }
      placeholder = "e.g., stationary" / > {
      } < Input 
      type = "text"
      name = "location"
      id = "loc"
      onChange = {
          this.handleChange
      }
      placeholder = "Location"
      value={this.state.location}
    />
   < Dropdown 
      id = 'distance'
      name = 'distance'
      size = "lg"
      isOpen = {
          this.state.dropdownOpen
      }
      toggle = {
          this.toggle
      } >
      < DropdownToggle caret > {
          this.state.distance
      } < /DropdownToggle> < DropdownMenu >
      < DropdownItem onClick = {
          this.select
      } > 5 mi < /DropdownItem> < DropdownItem onClick = {
          this.select
      } > 10 mi < /DropdownItem> < DropdownItem onClick = {
          this.select
      } > 25 mi < /DropdownItem> < DropdownItem onClick = {
          this.select
      } > 50 mi < /DropdownItem> < DropdownItem onClick = {
          this.select
      } > 100 mi < /DropdownItem> < /DropdownMenu> < /Dropdown>


      < Button 
      onClick = {
          this.handleSubmit
      } > < i className = "icon-magnifier" > < /i>&nbsp;Search</Button>
      < /form>
   );
  }
 }

这是我的路线设置方式:

class Full extends ComponentBase {

  constructor(props) {
    if (!props) props = {};
    super(props);
    this.state = {
      'city': '',
      'location': {},
      'contract_count': ''
    };

    const { dispatch } = this.props;
      history.listen((location, action) => {
      // clear alert on location change
      dispatch(alertActions.clear());
    });
  }

  componentDidMount() {
    if (this.state.contract_count == '') {
      infoService.info()
        .then(
          results => {
            this.setState({
              city: results.data.city,
              location: results.data.location,
              contract_count: results.data.contract_count
            });
          }
        )
    }
  }

  //wait to render until we have state...
  preRender() {
    if (this.state.contract_count == '') {
      //wait
      return (<div></div>);
    } else {
      return (
        <ConnectedRouter history={history} data={this.state}>
          <div
               className="app setFont">
          <Header city={this.state.city}/>
          <div className="app-body">

            <main className="main">
            <Breadcrumb />

              <Container fluid>
                <div>
                  <PropsRoute exact path="/" name="Home" component={Home} data={this.state}/>
                  <Route exact path="/dashboard" name="Dashboard" component={Dashboard} />
                  <Route exact path="/cart" name="Cart" component={Cart} />
                  <Route exact path="/invoice" name="Payment/Invoice" component={Invoice} />
                  <Route exact path="/login" name="Login" component={Login}/>
                  <Route exact path="/register" name="Register" component={InitialRegister}/>
                  <Route exact path="/add-company" name="Add Company" component={AddCompany}/>
                  <Route exact path="/add-credit-card" name="Add Credit Card" component={AddCreditCard}/>
                  <Route exact path='/results' name='Search Results' component={SearchResults} />
                </div>
              </Container>
            </main>
          </div>
          <Footer />
        </div>
        </ConnectedRouter>
      );
    }
  }


  render() {
    return(
      <div>
      {this.preRender.call(this)}
      </div>
    );
  }
}
const renderMergedProps = (component, ...rest) => {
  const finalProps = Object.assign({}, ...rest);
  return (
    React.createElement(component, finalProps)
  );
}

const PropsRoute = ({ component, ...rest }) => {
  return (
    <Route {...rest} render={routeProps => {
        return renderMergedProps(component, routeProps, rest);
    }}/>
  );
}

function mapStateToProps(state) {
    const { alert } = state;
    return {
        alert
    };
}
const connectedApp = connect(mapStateToProps)(Full, store);
export { connectedApp as Full };

1 个答案:

答案 0 :(得分:1)

您不应自行修改历史记录。相反,您应该存储重定向到该状态的路径,然后呈现<Redirect>组件as described in the react-router docs

class SearchBox extends Component {
    // ...

    handleSubmit = event => {

        // ...

        if (term && location) {
            this.setState({referrer: `/results?term=${term}&location=${location}`});
        }
    }

    render() {
        const {referrer} = this.state;
        if (referrer) return <Redirect to={referrer} />;

        // ...
    }
}