Javascript reactjs-应用程序不';从api获取数据后,无法更改状态

Javascript reactjs-应用程序不';从api获取数据后,无法更改状态,javascript,reactjs,callback,Javascript,Reactjs,Callback,我正在构建一个React新闻应用程序,从中获取数据。在主页上,我有一个搜索栏,用户在其中输入关键字以从API检索。当我输入关键字并按enter键时,状态会发生变化,结果会显示在页面上,但随后会立即刷新并显示默认页面 App.js: class App extends Component { constructor(props) { super(props); this.state = { articles: [], keyword: ''}; this.fetchNe

我正在构建一个React新闻应用程序,从中获取数据。在主页上,我有一个搜索栏,用户在其中输入关键字以从API检索。当我输入关键字并按enter键时,状态会发生变化,结果会显示在页面上,但随后会立即刷新并显示默认页面

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;
NewsList.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>
    )
  }
}
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
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);
导出类新闻列表扩展组件{
render(){
返回此.props.articles.map((article)=>(
));
} 
}
导出默认新闻列表
Article.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>
    )
  }
}
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
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);
类文章扩展组件{
render(){
常数{
标题
描述
出版,
来源:,
urlToImage,
网址
}=这篇文章;
const{classes}=this.props;
let date=新日期(publishedAt).toLocaleString();
返回(
{title}
{说明}
{source.name}
{date}
);
}
}
导出默认样式(样式)(文章);

我想你的问题在于:

let result = await fetch(url).then(response => response.json());
return result.articles.slice(0,20);
您正在等待获取,然后
。然后
以json的形式获取响应,但是,您正在返回
results.articles.slice
之前的
response.json()
解析

尝试:


我认为你的问题在于:

let result = await fetch(url).then(response => response.json());
return result.articles.slice(0,20);
您正在等待获取,然后
。然后
以json的形式获取响应,但是,您正在返回
results.articles.slice
之前的
response.json()
解析

尝试:


欢迎来到Stack Overflow kerq!您的
NewsList
组件是什么样子的?很难说为什么在没有看到它是如何实现的情况下不呈现任何内容。谢谢!我刚刚添加了NewsList.js和Article.js,我没有看到任何明显的错误。如果您的write
console.log(this.state.articles),您是否看到状态更新
应用程序
组件的呈现方法中?否,[]显示在控制台中。我认为,因为onSubmit事件允许尝试取消表单onSubmit事件。当发生提交事件时,请尝试将e.preventDefault()添加到第一条语句,以使页面重新加载欢迎使用堆栈溢出kerq!您的
NewsList
组件是什么样子的?很难说为什么在没有看到它是如何实现的情况下不呈现任何内容。谢谢!我刚刚添加了NewsList.js和Article.js,我没有看到任何明显的错误。如果您的write
console.log(this.state.articles),您是否看到状态更新
应用程序
组件的呈现方法中?否,[]显示在控制台中。我认为,因为onSubmit事件允许尝试取消表单onSubmit事件。当提交事件发生时,它会使您重新加载页面,并尝试将e.preventDefault()添加到第一条语句。我尝试了此操作,但没有解决我的问题。我认为数据被提取,状态被设置,然后页面被重新提交到默认值。那可能是什么原因?嗯。。我认为如果你更改应用程序组件上的
道具,它将从头开始重建组件,那么唯一会导致这种情况发生的事情就是。我尝试了这种方法,但没有解决我的问题。我认为数据被提取,状态被设置,然后页面被重新提交到默认值。那可能是什么原因?嗯。。我认为,如果您更改应用程序组件上的
道具,并且它将从头开始重建组件,那么唯一会导致这种情况发生的事情就是。