如何对道具更改进行 API 调用?

How to make an API call on props change?

我正在使用 this API

创建一个 hackernews 克隆

这是我的组件结构

-main
   |--menubar
   |--articles
   |--searchbar

下面是我用来从外部获取数据的代码块API。

componentWillReceiveProps({search}){
    console.log(search);
}

componentDidMount() {
    this.fetchdata('story');
}

fetchdata(type = '', search_tag = ''){
    var url = 'https://hn.algolia.com/api/v1/search?tags=';
    fetch(`${url}${type}&query=${search_tag}`)
    .then(res => res.json())
    .then(data => {
        this.props.getData(data.hits);
    });
}

我正在 componentDidMount() 生命周期方法中进行 API 调用(应该如此)并在启动时正确获取数据。 但是这里我需要通过 searchbar 组件将搜索值传递给 menubar 组件来进行自定义搜索。因为我只使用反应(不使用 redux atm),所以我将它作为 prop 传递给 menubar 组件。 作为提到的代码块,如果我搜索 react 并通过道具传递它,它会记录 react 一次(因为我在 componentWillReceiveProps()).但是,如果我在 componentWillReceiveProps 中使用 search 参数 运行 fetchData 方法,我收到它会进入无限循环。它甚至在我将搜索值作为道具传递之前就进入了无限循环。

所以在这里,我如何调用 fetchdata() 方法更新 props

我已经阅读了 Whosebug 答案,但是在 componentWillReceiveProps 中进行 API 调用不起作用。

那么我应该在哪里调用 fetchdata() 呢?这是因为异步吗?

更新 : codepen 项目

会不会是在 this.props.getData() 里面你改变了一个 state 值,最终作为 prop 传递?这将导致 componentWillReceiveProps 函数变为 re-called。 您可以通过检查 search 道具是否已在 componentWillReceiveProps:

中更改来解决此问题
componentWillReceiveProps ({search}) {
  if (search !== this.props.search) {
    this.fetchdata(search);
  }
}

你可以通过

componentWillReceiveProps({search}){
  if (search !== this.props.search) {
    this.fetchdata(search);
  }
}

但我认为正确的方法是在 componentDidUpdate 中进行,如 react docs 所说

This is also a good place to do network requests as long as you compare the current props to previous props (e.g. a network request may not be necessary if the props have not changed).

componentDidMount() {
  this.fetchdata('story');
}

componentDidUpdate(prevProps) {
  if (this.props.search !== prevProps.search) {
    this.fetchdata(this.props.search);
  }
}

为什么不通过组合来完成此操作并在 main HoC(高阶组件)中处理数据获取。

例如:

class SearchBar extends React.Component {
  handleInput(event) {
    const searchValue = event.target.value;
    this.props.onChange(searchValue);
  }

  render() {
    return <input type="text" onChange={this.handleInput} />;
  }
}

class Main extends React.Component {
  constructor() {
    this.state = {
      hits: []
    };
  }

  componentDidMount() {
    this.fetchdata('story');
  }

  fetchdata(type = '', search_tag = '') {
    var url = 'https://hn.algolia.com/api/v1/search?tags=';
    fetch(`${url}${type}&query=${search_tag}`)
      .then(res => res.json())
      .then(data => {
        this.setState({ hits: data.hits });
      });
  }

  render() {
    return (
      <div>
        <MenuBar />
        <SearchBar onChange={this.fetchdata} />
        <Articles data={this.state.hits} />
      </div>
    );
  }
}

main 组件中包含 fetchdata 函数并将其作为 onChange 函数传递给 SearchBar 组件,当搜索栏输入时将调用该函数更改(或按下搜索按钮)。

你怎么看?