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

时间:2018-03-07 09:02:15

标签: javascript reactjs react-props

我正在使用this API

创建黑客新闻克隆

这是我的组件结构

-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调用,并在启动时正确获取数据。 但在这里,我需要通过搜索栏组件将搜索值传递给菜单栏组件进行自定义搜索。由于我只使用反应(不使用redux atm),我将其作为prop传递给菜单栏组件。 如上面提到的代码块,如果我搜索做出反应并通过道具传递它,它会记录反应一次(因为我在componentWillReceiveProps()上调用它)。但是,如果我在fetchData componentWillReceiveProps内运行search方法,我会收到{无效循环'。甚至在我将搜索值作为道具传递之前,它就会进入无限循环。

所以在这里,如何通过更新fetchdata()来调用props方法?

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

那么在我的情况下,我应该在哪里拨打fetchdata()?这是因为异步吗?

项目的

更新codepen

3 个答案:

答案 0 :(得分:2)

你可以通过

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

但我认为正确的方法是在componentDidUpdate react docs

  

只要您将当前道具与之前的道具进行比较(例如,如果道具未更改,则可能不需要网络请求),这也是进行网络请求的好地方。

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

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

答案 1 :(得分:1)

是否可以在this.props.getData()内更改状态值,最终作为道具传递?这将导致重新调用componentWillReceiveProps函数。 您可以通过检查search中的componentWillReceiveProps道具是否已更改来解决此问题:

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

答案 2 :(得分:1)

为什么不通过组合来执行此操作并处理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>
    );
  }
}

拥有fetchdata组件中的main功能,并将其作为SearchBar组件传递给onChange组件,当搜索栏输入发生变化时,该功能将被调用(或按下搜索按钮。)

您怎么看?