Reputation: 49
I think I know what I need to do to make my searchLocationChange
function work, but I'm not sure quite how to do it. Please forgive the indentation, was grappling a fair bit with StackOverflow's WYSIWYG!
Here's my Parent component setup:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
forecasts: [],
location: {
city: '',
country: '',
},
selectedDate: 0,
searchText: '',
};
this.handleForecastSelect = this.handleForecastSelect.bind(this);
this.searchLocationChange = this.searchLocationChange.bind(this);
}
}
With this specific function I want to make work:
searchLocationChange() {
console.log(this.state.searchText);
Axios.get('https://mcr-codes-weather.herokuapp.com/forecast', {
params: {
city: this.state.searchText,
},
})
.then((response) => {
this.setState({
forecasts: response.data.forecasts,
location: {
city: response.data.location.city,
country: response.data.location.country,
}
});
});
}
And in my Child component, the logic is:
class SearchForm extends React.Component {
constructor(props) {
super(props);
this.state = {
searchText: '',
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const enteredText = event.target.value;
this.setState({
searchText: enteredText
});
}
render() {
return (
<span className="search-form">
<div className="search-form__input"><input type="text" value={this.state.searchText} onChange={this.handleInputChange} /></div>
<div className="search-form__submit"><button onClick={this.props.searchLocationChange}>Search</button></div>
</span>
);
}
}
I realise I'm trying to update the Parent component with searchText from the state of the Child component, but I can't figure out what I need to change to make this work. I have a sneaking suspicion I'm 99% of the way there, and it's only a few more lines I need, but I could be way off?
Upvotes: 1
Views: 58
Reputation: 677
You should call the function like that this.props.searchLocationChange(this.state.searchText)
You can do something like below
<div className="search-form__submit"><button onClick={() => {this.props.searchLocationChange(this.state.searchText)}}>Search</button></div>
and function definition should be
searchLocationChange(searchText) {
Upvotes: 1
Reputation: 3687
You are mixing controlled and uncontrolled. Either do controlled or uncontrolled. So take the search Text from parent only. Above solutiion is one way of doing this . Another way is to pass searchTxt from parent to child.
<SearchForm
searchTxt={this.state.searchTxt}
handleInputChange={this.handleInputChange}
searchLocationChange={this. searchLocationChange}
/>
Move your handleInputChange in parent:
handleInputChange = (event) => {
const enteredText = event.target.value;
this.setState({ searchText: enteredText });
}
Then change your child component respective line to
<div className="search-form__input"><input type="text" value={this.props.searchText} onChange={this.props.handleInputChange} /></div>
Now when you try the above code it should work. Now you are keeping your searchTxt in the parent component. your SearchForm component is Completely controlled now.
Upvotes: 0
Reputation: 8102
You're already passing down searchLocationChange
from your parent.
in parent component:
searchLocationChange(searchedText) {
console.log(searchText);
Axios.get('https://mcr-codes-weather.herokuapp.com/forecast', {
params: {
city: searchText,
},
})
.then((response) => {
this.setState({
forecasts: response.data.forecasts,
location: {
city: response.data.location.city,
country: response.data.location.country,
},
});
});
}
in child:
render() {
const { searchText } = this.state;
return (
<span className="search-form">
<div className="search-form__input"><input type="text" value={this.state.searchText} onChange={this.handleInputChange} /></div>
<div className="search-form__submit"><button onClick={()=>{this.props.searchLocationChange(searchText)}}>Search</button></div>
</span>
);
}
Upvotes: 2