I am building a simple weather app where I set a place to display the weather forcast with a boolean to control if it will show or not
<div className="column">
{this.state.displayResult ? <WeatherResult /> : null}
</div>
There the displayResult boolean will set to true by the handleSubmit() in the form and the fetchFavWeather() on the buttons, and will set to be false by HandleInputChange() in the first control class
async getCoord() {
let city = {
cityname: this.state.postcodeInput
}
axios.post('http://localhost:4001/search-location', city)
.then((response) => {
console.log(response);
this.setState({
displayResult: true
});
}, (error) => {
console.log(error);
});
}
handleSubmit(e) {
e.preventDefault();
this.getCoord();
}
handleInputChange(e) {
this.setState({
postcodeInput: e.target.value,
displayResult: false
});
}
fetchFavWeather(city){
this.setState({
displayResult: false,
postcodeInput: city
},()=>{
console.log("passing fav to forcast" + this.state.postcodeInput);
this.getCoord()
});
}
fetchFavCities(){
axios.get('http://localhost:4001/favouriteCites')
.then((res)=>{
this.setState({
favCts: res.data
})
});
}
render() {
this.fetchFavCities();
return (
<div>
<form onSubmit={this.handleSubmit}>
<div>
<div className="column">
{
this.state.favCts.map(
(item, index) => <button key={index} onClick = {() => {this.fetchFavWeather(item)}}>{item}</button>
)}
</div>
<div className="control">
<input className="input" type="text" placeholder="input city here" onChange={this.handleInputChange} required />
</div>
<div className="field">
<div className="control">
<input type='submit' className="button is-light is-large" value='Check Weather' />
<input type='submit' className="button is-light is-large" value='Save as Favourite' onClick = {this.saveAsFavourite}/>
</div>
</div>
</div>
</form>
<div className="column">
{this.state.displayResult ? <WeatherResult /> : null}
</div>
</div>
)
}
however in my WeatherResult Component class, I found out that the render() is being called in an infinite loop, any ideas why?
class WeatherResult extends React.Component {
constructor(props) {
super(props);
this.state = {
currentTemp: '',
humidity: '',
cityName: '',
days: []
}
}
async fetchWeather() {
let response = await fetch('http://localhost:4001/weather');
await response.json().then(data => {
console.log(data);
this.setState({
currentTemp: data['currentConditions']['temp'] + '°C',
//humidity: data.main.humidity + '%',
cityName: data.address,
days: data.days
})
})
}
componentDidMount() {
this.fetchWeather();
}
render() {
//console.log("why is this looping?");
return (
<div>
<p>Current Conditions at {this.state.cityName}</p>
<p>Current temperature: {this.state.currentTemp}</p>
<p>Humidity: {this.state.humidity}</p>
<p>Location: {this.state.cityName}</p>
<div>
<p>Forcast</p>
<p>Date: {this.state.days['datetime']}</p>
<p>weatherType: {this.state.days['icon']}</p>
</div>
</div>
)
}
}
export default WeatherResult;
You are called a fetch method inside your render function which will cause an infinite update loop.
render() {
this.fetchFavCities();
Infinite loop will happen because you probably set these favorite cities in your state and reference them here
<div className="column">
{
this.state.favCts.map(
(item, index) => <button key={index} onClick = {() => {this.fetchFavWeather(item)}}>{item}</button>
)}
</div>
Place this outside of render function.
I have the next state:
const [social_networks, setSocial_networks] = useState([
{
social_account_type: "personal",
social_network: "linkedin",
handle: "",
content: ""
},
{
social_account_type: "company",
social_network: "twitter",
handle: "",
content: ""
},
{
social_account_type: "personal",
social_network: "webpage",
handle: "",
content: ""
}
])
In the parent component I declare the function:
const handleInputChange = (e, index) => {
const { name, value } = e.target;
const list = [...social_networks];
list[index][name] = value;
setSocial_networks(list);
};
Set this to the children in the next code:
social_networks.map((social_network, idx) => {
if (social_network.social_account_type == "personal") return <div key={idx}><AccountsPill handle={social_network.handle} social={social_network.social_network} content={social_network.handle} index={idx} handleInputChange={handleInputChange} /> </div>
})
And into my child component I have the next code:
<div className="row m-0">
<div className="svg-container col-md-1">
<BrowserIcon color="#868E96" />
</div>
<input type="text" className="col-md-11 set-account-input" placeholder=
{"www."+props.social+".com"} name="handle" id="handle" defaultValue={props.handle}
onChange={e => props.handleInputChange(e, props.index)} />
</div>
<div className="row m-0">
<div className="svg-container col-md-1">
<AtIcon color="#868E96" />
</div>
<input type="text" className="col-md-11 set-account-input" placeholder="MyUsername"
name="content" id="content" defaultValue={props.content} onChange={e =>
props.handleInputChange(e, props.index)} />
</div>
The page show me like that:
after rendering frontpage
When I change the input.Content works fine:
input.name=content change
But, if I change the input.name=handle , change the other input too:
input.name=handle change
I tried to make two differents handleChange functions, change the props.name, add the props.id, but does'nt works yet.
You passed wrong content props to your AccountsPill component, it should be
<AccountsPill
handle={social_network.handle}
social={social_network.social_network}
content={social_network.content}
index={idx}
handleInputChange={handleInputChange}
/>
I think your problem is that const list = [...social_networks]; shallow copies the state array, so it's really just an array of the original state objects. Try instead:
const handleInputChange = (e, index) => {
const { name, value } = e.target;
const list = social_networks.map((social, i)=>{
if(index === i){
return {...social, [name]: value}
}
return {...social}
})
setSocial_networks(list);
};
I am trying to edit the value from table and put it in textbox. When I Click edit button it says "Cannot read property edit name of undefined". I have used fat arrow functions. I also used bind in the constructor but it has same error. Below is My Code. When Clicked on editName button, it gives error.
class App extends React.Component {
constructor(props) {
super(props);
this.onNameChange = this.onNameChange.bind(this);
this.onSurnameChange = this.onSurnameChange.bind(this);
this.onIdChange = this.onIdChange.bind(this);
this.editName = this.editName.bind(this);
this.state = {
data: "",
name: "",
surname: "",
id: ""
};
}
componentDidMount() {
axios.get("http://localhost:4000/employees").then((response, err) => {
if (err) {
console.log("err");
}
this.setState(prevstate => ({
data: response.data
}));
});
}
handleSumbit(e) {
axios
.post("http://localhost:4000/employees", {
name: this.state.name,
surname: this.state.surname,
id: this.state.id
})
.then((response, err) => {
if (err) {
console.log("Error While Posting Data", err);
}
console.log("RESPONSE FROM POST", response);
});
}
onNameChange(e) {
this.setState({
name: e.target.value
});
}
onSurnameChange(e) {
this.setState({
surname: e.target.value
});
}
onIdChange(e) {
this.setState({
id: e.target.value
});
}
editName(value) {
this.setState({
name: value
});
}
editSurname(e, value) {
this.setState({
surname: value
});
}
render() {
const { data } = this.state;
return (
<div className="container">
<div>
<label className="">Name</label>
<input
type="text"
name=""
value={this.state.name}
onChange={e => this.onNameChange(e)}
/>
</div>
<div>
<label className="">Surname</label>
<input
type="text"
name=""
value={this.state.surname}
onChange={e => this.onSurnameChange(e)}
/>
</div>
<div>
<label className=""> YOUR ID </label>
<input
type="number"
name=""
value={this.state.id}
onChange={e => this.onIdChange(e)}
/>
</div>
<div>
<button type="button" onClick={e => this.handleSumbit(e)}>
Sumbit
</button>
</div>
<div className="main-container">
{data &&
data.map(function(data, key) {
return (
<React.Fragment>
<div className="child">
{data.name}
<button onClick={e => this.editName("Samar")}>Edit</button>
</div>
<div className="child">
{data.surname}
<button onClick={e => this.editSurname(e, data.surname)}>
Edit
</button>
</div>
</React.Fragment>
);
})}
</div>
</div>
);
}
}
export default App;
I have noticed (as #DanO said) this becomes not a window object but a undefined when using inside map function in render method. The solution is dead simple, either change it to arrow function (preferred) or use Function.prototype.bind.
data.map((data, key) => (<>...</>))
I'm having a issue with React.
my parent component:
class RoomPrice extends React.Component {
constructor(props){
super(props)
this.state = {
room: this.props.room,
prices: []
};
this.handleDeletePrice = this.handleDeletePrice.bind(this);
}
handleDeletePrice(price_index){
let prices = this.state.prices;
prices.splice(price_index, 1);
this.setState({prices: prices});
}
listPrices(){
console.log(this.state.prices)
return this.state.prices.map((item, index) => {
return (
<AdditionalPrice
key={index}
price={item}
index={index}
handleDeletePrice={this.handleDeletePrice}
/>
)
});
}
renderBasePrice(){
return(
<div id="list_prices">
{ this.listPrices() }
</div>
)
}
render(){
return(
<div>
{this.renderBasePrice()}
</div>
)
}
}
my child component
class AdditionalPrice extends React.Component {
constructor(props){
super(props)
this.state = {
price: this.props.price
}
this.handleKeyChange = this.handleKeyChange.bind(this);
this.handleValueChange = this.handleValueChange.bind(this);
this.handleDeletePrice = this.handleDeletePrice.bind(this);
}
componentWillReceiveProps(nextProps){
this.setState({price: nextProps.price})
}
handleKeyChange(event){
let price = this.state.price;
price.key = event.target.value
this.setState({price: price})
}
handleValueChange(event){
let price = this.state.price;
price.value = event.target.value
this.setState({price: price})
}
handleDeletePrice(){
this.props.handleDeletePrice(this.props.index);
}
renderForm(){
let key = this.state.price.key;
let value = this.state.price.value;
return(
<div className="form-row">
<div className="col-5">
<input type="text" className="form-control" placeholder="Key" onChange={this.handleKeyChange} required/>
</div>
<div className="col-5">
<input type="number" className="form-control" placeholder="Value" onChange={this.handleValueChange} required/>
</div>
<div className="col-2">
<button className="btn btn-warning" type="button" onClick={this.handleDeletePrice}>
<i className="material-icons">delete_forever</i>
</button>
</div>
<input type="hidden" className="form-control" name={"base_price["+key+"]"} value={value} />
</div>
)
}
render() {
return(
<div>
{this.renderForm()}
</div>
)
}
}
i try to delete a item which was get in children, but it always removes last element instead. I thought it have some problem with index
I want to delete the particular element, it always deletes the last element from the render list array.
please help me to sort this problem
Try doing this instead.
handleAddNewPrice(){
const { prices } = this.state;
let new_price = {"key": "", "value": ""}
this.setState({ prices: [...prices, new_price] })
}
Edit
and also this:
handleDeletePrice(price_index){
let prices = [...this.state.prices]; //make a seperate copy of state.
prices.splice(price_index, 1);
this.setState({prices: prices});
}
Problem is in your props. The props.index is received once, so if you want to the delete function worked you need use props.index as a state like price. This is sample codes you need to change in the AdditionalPrice Component:
this.state = {
price: this.props.price,
index: this.props.index
}
componentWillReceiveProps(nextProps){
this.setState({
price: nextProps.price,
index: nextProps.index
})
}
handleDeletePrice(){
this.props.handleDeletePrice(this.state.index);
}
i found the problem
my field in child component haven't set the value. see below
<input type="text" className="form-control" placeholder="Key" value={key} onChange={this.handleKeyChange} required/>
thanks all
I am developing a React JS web application where I have a form with four select fields (Make, Model, Min price and Max price) and a Search button. The data for search results will be fetched from API according to the selection of options. I want to show that data on another page in a card (page route path: /search) when user clicked on search button. I am using react router. The API url/end point is https://mysterious-journey-51969.herokuapp.com/api/search-vehicle/?q=mercedes&m=sprinter&pf=0&pt=100000 where "q" field matches Vehicle Make, "m" field matches Model, "pf" field matches Min Price, "pt" field matches Max Price. How I can do that?
Here is my Form component code:
import React, { Component } from 'react';
import { Form, FormGroup, Input } from 'reactstrap';
import { veh_data } from '../shared/vehicle_make_and_models';
const defaultValues = [
{ value: 0, text: 0, key: 1 },
{ value: 500, text: 500, key: 2 },
{ value: 1000, text: 1000, key: 3 },
{ value: 1500, text: 1500, key: 4 },
{ value: 2000, text: 2000, key: 5 },
{ value: 2000, text: 2000, key: 6 }
];
const MIN_TITLE = { selected: true, disabled: true, text: 'Min Price' };
const MAX_TITLE = { selected: true, disabled: true, text: 'Max Price' };
class ImgAndForm extends Component {
constructor(props) {
super(props);
this.handleSearch = this.handleSearch.bind(this);
this.keyToOption = this.keyToOption.bind(this);
this.renderOptions = this.renderOptions.bind(this);
this.handleModelChange = this.handleModelChange.bind(this);
this.state = {
minData: [MIN_TITLE, ...defaultValues],
maxData: [MAX_TITLE, ...defaultValues],
minValue: null,
maxValue: null,
modelSelected: null
};
}
renderOptions(data) {
return data.map(datum => {
// this allows us to indicate whether we are selecting or disabling
const selected = datum.selected || false;
const disabled = datum.disabled || false;
return (
<option key={datum.key} value={datum.value} selected={selected} disabled={disabled}>
{datum.text}
</option>
);
});
}
handleModelChange(event) {
console.log(event.target.value);
this.setState({ modelSelected: event.target.value });
}
handleSearch(event) {
alert("Search button clicked");
}
keyToOption(key) {
return key.split("-")
.map(word => word.slice(0, 1).toUpperCase() + word.slice(1))
.join(" ");
}
handleMinSelect = event => {
const value = event.target.value;
const newMaxValues = [];
defaultValues.forEach(datum => {
if (datum.value >= Number.parseInt(value, 10)) {
newMaxValues.push(datum);
}
});
this.setState({
maxData: [MAX_TITLE, ...newMaxValues],
minValue: value
});
};
handleMaxSelect = event => {
const value = event.target.value;
this.setState({ maxValue: value });
};
render() {
const vehicles = veh_data.reduce((acc, veh, i) => {
let make = Object.keys(veh)[0],
vehModels = veh[make];
return {
makes: [
...acc.makes,
<option key={make + i} value={make}>{this.keyToOption(make)}</option>
],
models: {
...acc.models,
[make]: vehModels.map((model, i) => {
return (
<option key={make + model + i} value={model}>
{this.keyToOption(model)}
</option>
);
})
}
};
}, { makes: [], models: [] });
const selectedModels =
this.state.modelSelected && this.state.modelSelected.length ? (
vehicles.models[this.state.modelSelected]
) : (
<option value="">Model (select make first)</option>
);
return (
<div>
<header className="headerbg d-flex">
<div className="container my-auto">
<div className="row">
<div className="offset-1 col-10 offset-lg-0 col-lg-4">
<div id="search-form-div" className="container">
<div className="row">
<div className="col-12 my-4">
<h3>Search</h3>
<Form onSubmit={this.handleSearch}>
<FormGroup>
<Input
onChange={e => this.handleModelChange(e)}
type="select"
name="q"
id="q"
>
<option value="">Make</option>
{vehicles.makes}
</Input>
</FormGroup>
<FormGroup>
<Input type="select" name="m" id="m">
{selectedModels}
</Input>
</FormGroup>
<FormGroup>
<Input type="select"
name="pf"
id="pf"
value={this.state.minValue}
onChange={this.handleMinSelect}>
{this.renderOptions(this.state.minData)}
</Input>
</FormGroup>
<FormGroup>
<Input
type="select"
name="pt"
id="pt"
value={this.state.maxValue}
onChange={this.handleMaxSelect}>
{this.renderOptions(this.state.maxData)}
</Input>
</FormGroup>
<FormGroup>
<Input type="submit" name="search" id="search" className="btn btn-primary" value="Search" />
</FormGroup>
</Form>
</div>
</div>
</div>
</div>
</div>
</div>
</header>
</div>
);
}
}
export default ImgAndForm;
Here is my Search result component code:
import React, { Component } from 'react';
import Smallheader from './SmallHeader';
import { Card, CardImg, CardTitle, CardSubtitle } from 'reactstrap';
class SearchResult extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<div>
<Smallheader />
<div className="my-5">
<div className="container text-center" id="contactContainer">
<div className="row">
<div className="col-lg-12 mx-auto">
<h2 className="text-center">Search Results</h2>
<hr className="my-4 thick-hr" />
</div>
</div>
<div className="row">
<div className="col-6 col-lg-3 mt-4">
<Card>
<a href="#">
<CardImg src="" className="img-fluid" />
<CardTitle>Title Here</CardTitle>
<CardSubtitle>Price Here</CardSubtitle>
</a>
</Card>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default SearchResult;
Here is a working solution...
https://codesandbox.io/s/lrv2w3qxlq?moduleview=1
I've imported your SearchResults component and put it directly below your ImgAndForm, but you can move it anywhere in that render function.
For this specific situation you would need a way to render this on a new 'page' you would need a way to manage shared application state, like Redux or at least a container component as #MikeZinn mentioned, but to do that properly would require as significant amount of work to implement the routing and re-architect your entire program. (If you want I can show you a small hack to produce the same result without that for now, but I'd advise looking into a more permanent solution.)
Since the SearchResults component can be 'stateless' I removed the constructor function, but I left it as a class for now because this component will likely need state eventually.
I added the axios library to fetch the data from the API, but any other XHR module already used in your program will do.
NOTE: Since the specific API endpoints that your form is currently able to query are unavailable, I've hard coded the 'mercedes' example you provided, but the program will log both 'realQuery' and 'dummyQuery' so you see that it is producing the correct query structure for whenever you fix that.
Form Component
import React, { Component } from "react";
import { Form, FormGroup, Input } from "reactstrap";
// import { veh_data } from '../shared/vehicle_make_and_models';
import SearchResult from "./result";
import axios from "axios";
const veh_data = [
{ "alfa-romeo": ["145", "90", "Alfa 6", "Alfasud"] },
{ "aston-martin": ["15", "2-Litre", "AM Vantage", "Atom", "Cygnet", "DB2"] },
{ audi: ["100", "200", "A1", "A2", "A3", "A4", "A5", "A6", "A7"] }
];
const defaultValues = [
{ value: 0, text: 0, key: 1 },
{ value: 500, text: 500, key: 2 },
{ value: 1000, text: 1000, key: 3 },
{ value: 1500, text: 1500, key: 4 },
{ value: 2000, text: 2000, key: 5 },
{ value: 2000, text: 2000, key: 6 }
];
const MIN_TITLE = { selected: true, disabled: true, text: "Min Price" };
const MAX_TITLE = { selected: true, disabled: true, text: "Max Price" };
class ImgAndForm extends Component {
constructor(props) {
super(props);
this.handleSearch = this.handleSearch.bind(this);
this.keyToOption = this.keyToOption.bind(this);
this.renderOptions = this.renderOptions.bind(this);
this.handleModelChange = this.handleModelChange.bind(this);
this.state = {
minData: [MIN_TITLE, ...defaultValues],
maxData: [MAX_TITLE, ...defaultValues],
minValue: "",
maxValue: "",
modelSelected: "",
makeSelected: "",
searchResults: ""
};
}
renderOptions(data) {
return data.map(datum => {
// this allows us to indicate whether we are selecting or disabling
const selected = datum.selected || false;
const disabled = datum.disabled || false;
return (
<option
key={datum.key}
value={datum.value}
selected={selected}
disabled={disabled}
>
{datum.text}
</option>
);
});
}
handleModelChange(event) {
console.log(event.target.value);
this.setState({ modelSelected: event.target.value });
}
handleMakeChange(event) {
console.log(event.target.value);
this.setState({ makeSelected: event.target.value });
}
async handleSearch(event) {
event.preventDefault();
alert("Search button clicked");
let { makeSelected, modelSelected, minValue, maxValue } = this.state;
let realQuery =
"https://mysterious-journey-51969.herokuapp.com/api/search-vehicle/?" +
`q=${makeSelected.split("-").join("")}` +
`&m=${modelSelected.split("-").join("")}` +
`&pf=${minValue}` +
`&pt=${maxValue}`;
let dummyQuery =
"https://mysterious-journey-51969.herokuapp.com/api/search-vehicle/?q=mercedes&m=sprinter&pf=0&pt=100000";
console.log("realQuery (was not run)", realQuery);
console.log("dummyQuery (was run)", dummyQuery);
let res = await axios.get(dummyQuery).catch(err => console.log(err));
console.log("res", res.data);
if (res && res.data) {
this.setState(prevState => {
return {
...prevState,
searchResults: res.data
};
});
}
}
keyToOption(key) {
return key
.split("-")
.map(word => word.slice(0, 1).toUpperCase() + word.slice(1))
.join(" ");
}
handleMinSelect = event => {
const value = event.target.value;
const newMaxValues = [];
defaultValues.forEach(datum => {
if (datum.value >= Number.parseInt(value, 10)) {
newMaxValues.push(datum);
}
});
this.setState({
maxData: [MAX_TITLE, ...newMaxValues],
minValue: value
});
};
handleMaxSelect = event => {
const value = event.target.value;
this.setState({ maxValue: value });
};
render() {
const vehicles = veh_data.reduce(
(acc, veh, i) => {
let make = Object.keys(veh)[0],
vehModels = veh[make];
return {
makes: [
...acc.makes,
<option key={make + i} value={make}>
{this.keyToOption(make)}
</option>
],
models: {
...acc.models,
[make]: vehModels.map((model, i) => {
return (
<option key={make + model + i} value={model}>
{this.keyToOption(model)}
</option>
);
})
}
};
},
{ makes: [], models: [] }
);
const selectedModels =
this.state.makeSelected && this.state.makeSelected.length ? (
vehicles.models[this.state.makeSelected]
) : (
<option value="">Model (select make first)</option>
);
return (
<div>
<header className="headerbg d-flex">
<div className="container my-auto">
<div className="row">
<div className="offset-1 col-10 offset-lg-0 col-lg-4">
<div id="search-form-div" className="container">
<div className="row">
<div className="col-12 my-4">
<h3>Search</h3>
<Form onSubmit={this.handleSearch}>
<FormGroup key={1}>
<Input
onChange={e => this.handleMakeChange(e)}
type="select"
name="q"
id="q"
>
<option value="">Make</option>
{vehicles.makes}
</Input>
</FormGroup>
<FormGroup key={2}>
<Input
onChange={e => this.handleModelChange(e)}
type="select"
name="m"
id="m"
>
{selectedModels}
</Input>
</FormGroup>
<FormGroup key={3}>
<Input
type="select"
name="pf"
id="pf"
value={this.state.minValue}
onChange={this.handleMinSelect}
>
{this.renderOptions(this.state.minData)}
</Input>
</FormGroup>
<FormGroup key={4}>
<Input
type="select"
name="pt"
id="pt"
value={this.state.maxValue}
onChange={this.handleMaxSelect}
>
{this.renderOptions(this.state.maxData)}
</Input>
</FormGroup>
<FormGroup key={5}>
<Input
type="submit"
name="search"
id="search"
className="btn btn-primary"
value="Search"
/>
</FormGroup>
</Form>
<SearchResult results={this.state.searchResults} />
</div>
</div>
</div>
</div>
</div>
</div>
</header>
</div>
);
}
}
export default ImgAndForm;
Results Component
import React, { Component } from "react";
// import Smallheader from './SmallHeader';
import { Card, CardImg, CardTitle, CardSubtitle } from "reactstrap";
class SearchResult extends Component {
renderResults() {
let { results } = this.props;
console.log("results", results);
if (results && results.length) {
return results.map(({ price, text, title, remote_image }, i) => {
return (
<Card key={"card-" + i}>
<a href="#">
<CardImg src={remote_image} className="img-fluid" />
<CardTitle>{title}</CardTitle>
<CardSubtitle>{price}</CardSubtitle>
</a>
</Card>
);
});
}
}
render() {
return (
<div>
{/* <Smallheader /> */}
<div className="my-5">
<div className="container text-center" id="contactContainer">
<div className="row">
<div className="col-lg-12 mx-auto">
<h2 className="text-center">Search Results</h2>
<hr className="my-4 thick-hr" />
</div>
</div>
<div className="row">
<div className="col-6 col-lg-3 mt-4">{this.renderResults()}</div>
</div>
</div>
</div>
</div>
);
}
}
export default SearchResult;
This is exactly the type of problem Redux Solves without using Redux you will need to store the state on a shared parent component. For example,
class Search extends Component {
state = {
searchResult: null,
};
handleSearch = searchResult => {
this.setState({
searchResult,
});
}
render(){
const { searchResult, } = this.state;
if(searchResult === null){
return (
<ImgAndForm handleSearch={this.handleSearch} />
);
}
return (
<SearchResult searchResult={searchResult} />
);
}
}