Я создаю новостное приложение React, которое получает данные из News API . На главной странице у меня есть панель поиска, где пользователь вводит ключевые слова, чтобы получить от API. Когда я ввожу ключевое слово и нажимаю ввод, состояние изменяется, и результаты отображаются на странице, но затем сразу же обновляется и отображает страницу по умолчанию.
App.js:
class App extends Component {
constructor(props) {
super(props);
this.state = { articles: [], keyword: ''};
this.fetchNewsWithKeywords = this.fetchNewsWithKeywords.bind(this);
}
fetchNewsWithKeywords(keyword){
searchForKeywords(keyword)
.then(articles => this.setState({ articles: articles, keyword: keyword}))
}
render() {
return (
<Router >
<div className="App">
<div className="container" >
<Header/>
<Route exact path="/" render={props => (
<React.Fragment>
<SearchNews fetchNewsWithKeywords = {this.fetchNewsWithKeywords.bind(this)}/>
<NewsList articles = {this.state.articles}/>
</React.Fragment>
)} />
<Route path="/top-headlines" component={TopHeadlines} />
<Route path="/newest" component={Newest} />
</div>
</div>
</Router>
);
}
}
export default App;
SearchNews.js
class SearchNews extends Component {
state = {
value: ""
}
onSubmit = (e) => {
var str = this.state.value;
this.props.fetchNewsWithKeywords(str)
}
handleOnChange = event => {
this.setState({
value: event.target.value
})
};
render() {
const { classes } = this.props;
return (
<form className={classes.container} noValidate autoComplete="off" onSubmit={this.onSubmit}>
<TextField
id="outlined-search"
label="Search"
type="search"
className={classes.textField}
margin="normal"
variant="outlined"
onChange={this.handleOnChange}
/>
</form>
)
}
}
функция для извлечения данных из API
export async function searchForKeywords(keyword){
var query = keyword
var url = "https://newsapi.org/v2/everything?q="+
encodeURIComponent(query) +
"&apiKey="+API_KEY;
let result = await fetch(url).then(response => response.json());
return result.articles.slice(0,20);
NewsList.js
export class NewsList extends Component {
render() {
return this.props.articles.map((article) => (
<div className="gridContainer">
<div className="gridItem" >
<Article article = {article}/>
</div>
</div>
));
}
}
export default NewsList
Article.js
class Article extends Component {
render() {
const {
title,
description,
publishedAt,
source,
urlToImage,
url
} = this.props.article;
const { classes } = this.props;
let date = new Date(publishedAt).toLocaleString();
return (
<Card className={classes.card} >
<CardActionArea href={url} target="_blank">
<CardMedia
className={classes.media}
image={urlToImage}
title={title}
/>
<CardContent >
<Typography gutterBottom variant="h5" component="h2">
{title}
</Typography>
<Typography component="p">
{description}
</Typography>
<Typography variant="caption">
{source.name}
</Typography>
<Typography variant="caption">
{date}
</Typography>
</CardContent>
</CardActionArea>
</Card>
);
}
}
export default withStyles(styles)(Article);