如何在React组件prop更改时获取数据?

时间:2016-08-17 15:27:16

标签: javascript reactjs react-router

我的TranslationDetail组件在打开时传递一个id,并且基于此,在类构造函数中触发外部api调用,将数据接收到状态,并且此数据显示在TranslationDetail上。

//Routing:
<Route path="/translation/:id" component={TranslationDetail}/>

//Class:    
class TranslationDetail extends Component {
  constructor(props){
    super(props);

    this.props.fetchTrans(this.props.params.id);
  }

如果我手动输入网址,这一切都正常。如果我想使用react-router,例如为了显示下面的下一个项目,url确实发生了变化,但是没有触发api调用,数据将保持不变。

<button 
  type="button"
  onClick={() => 
    browserHistory.push(`/translation/${Number(this.props.params.id)+1}`)}>
  Next
</button>

请记住,我是一个初学者。发生这种情况的原因是我认为构造函数只运行一次,因此不会触发进一步的api调用。

我该如何解决这个问题? 我是否需要列出道具并在变更时调用函数?如果是,怎么样?

4 个答案:

答案 0 :(得分:70)

构造函数不是进行API调用的正确位置。

您需要使用生命周期事件:

确保将道具与componentDidUpdate中之前的道具进行比较,以避免在您关注的特定道具没有改变的情况下取道。

class TranslationDetail extends Component {    
   componentDidMount() {
     this.fetchTrans();
   }

   componentDidUpdate(prevProps) {
     if (prevProps.params.id !== this.props.params.id) {
       this.fetchTrans();
     }
   }

   fetchTrans() {
     this.props.fetchTrans(this.props.params.id);
   }
}

答案 1 :(得分:5)

从React 16.3及以后componentWillMountcomponentWillUpdatecomponentWillReceivePropsdeprecated

您可以使用静态getDerivedStateFromProps并根据道具上的更改返回新状态。

您无权访问道具这样的对象,因此您无法将nextPropsprops的当前nextProps.sth !== this.props.sth进行比较。您可以将prevState值与nextProps进行比较,并返回新的州值。

请立即向当前UNSAFE_添加componentWillMount以及其他已弃用的生命周期方法。

答案 2 :(得分:2)

使用 componentWillMount 获取数据并设置状态。 然后使用 componentWillReceiveProps 来捕获道具上的更新。

您可以查看Component Specs and Lifecycle

答案 3 :(得分:0)

我会使用render方法。如果未加载数据,我将呈现加载器微调器并抛出获取数据的操作。为此我通常使用商店。一旦商店从api获得数据,将数据标记为已加载,抛出事件并让组件从商店获取数据,用您的数据表示替换加载器微调器。