【问题标题】:How to make an API call on props change?如何对道具进行 API 调用更改?
【发布时间】:2018-08-15 07:30:34
【问题描述】:

我正在使用this API 创建一个hackernews-clone

这是我的组件结构

-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 组件来进行自定义搜索。因为我只使用 react(不使用 redux atm),所以我将它作为 prop 传递给 menubar 组件。 正如提到的代码块,如果我搜索 react 并通过 props 传递它,它会记录一次 react(我在 componentWillReceiveProps() 上调用它)。但是,如果我在 componentWillReceiveProps 中使用 search 参数运行 fetchData 方法,我会收到一个无限循环。甚至在我将搜索值作为道具传递之前,它就进入了无限循环。

那么在这里,我如何调用fetchdata() 方法来更新props

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

那么我应该在哪里打电话给fetchdata()?这是因为异步吗?

更新:项目的codepen

【问题讨论】:

    标签: javascript reactjs react-props


    【解决方案1】:

    你可以这样做

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

    但我认为正确的方法是在 componentDidUpdate 中以 react docs 说的方式进行操作

    只要将当前的 props 与以前的 props 进行比较,这也是进行网络请求的好地方(例如,如果 props 没有更改,则可能不需要网络请求)。

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

    【讨论】:

    • 非常感谢。这行得通。但是为什么你提到第二种方法是正确的方法呢?
    • 对我来说,componentWillReceiveProps 是某种准备,而不是执行业务逻辑的地方。但可能还有其他提及。
    【解决方案2】:

    为什么不只是通过组合来实现这一点,并在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 函数传递给onChange 函数,该函数将在搜索栏输入更改(或按下搜索按钮)时调用。

    你怎么看?

    【讨论】:

    • 谢谢。但我正在考虑保持main 组件清洁。这就是我在menubar 组件上使用API​​ 调用的原因。我对反应有点陌生。所以 HOC 对我来说还是有点困惑。无论如何谢谢。
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2020-09-01
      • 1970-01-01
      • 2017-08-05
      • 1970-01-01
      • 2019-09-26
      • 2019-06-02
      • 2015-11-24
      • 2013-12-15
      • 1970-01-01
      相关资源
      最近更新 更多