使用react调用api的正确方法

时间:2017-11-15 19:12:34

标签: javascript reactjs d3.js react-native

我有一个如下的反应代码,它基本上创建了一个树形图:

class ChartModal extends Component{
   constructor(props){
      super(props)
}
callApi(){

  fetch(someurl)
  .then((result) => {

    return result.json();
  }).then((jsonResult) => {
    console.log(jsonResult);
  })
}
render(){
  return(
    <Modal
            onOk={() => this.props.toggleVisibility()}
            onCancel={() => this.props.toggleVisibility()}
            visible={this.props.isVisible}
            okText={'ok'}
            cancelText={'cancel'}
            confirmLoading={false}
            title="Intent distribution chart"
        >
            <h1>HOWDY</h1>
            <TreeMap
                data =  {this.callApi()}//this is where i want the data returned by apicall
                width={400}
                valueUnit={'count'}
            />
        </Modal>
    )
  }
}

现在我希望api调用返回的数据在tree map组件中使用,但我现在这样做的方式似乎并没有起作用。 当我运行此操作时,tree map中的数据会显示为空,但我希望json返回api call

2 个答案:

答案 0 :(得分:4)

您需要在componentWillMount或任何其他生命周期挂钩中调用API,并在API回调中使用setState来确保将结果设置为组件状态变量。这样,setState您的组件可以访问API调用解析的值。

注意:this.state.result在第一次渲染期间将为null。在访问TreeMap之前,请确保在this.props.data组件中进行空检查。

IMP NOTE

@ aram90 对未安装组件的setState调用提出了很好的建议。为了避免这种this.canSetState,实例变量由我定义并添加以防止对未安装的组件进行任何可能的setState调用。

我使用这种方法只是为了尽可能早地调用API,即使它意味着纳秒。但是,另一种方法是在componentDidMount中调用API,然后相应地检查this._ismounted实例变量。有关此结帐的详情,请在此处Is there a way to check if the react component is unmounted?给出答案。 React docs建议不要使用isMounted()

有很多方法可以达到这个目的,但这更像是React。

class ChartModal extends Component{
  constructor(props){
    super(props)

    this.state = {
      result: null
    }
    this.canSetState = false;
  }

  componentWillMount() {
    this.canSetState = true;
    this.callApi();
  }

  componentWillUnmount() {
    this.canSetState = false;
  }

  callApi(){

    fetch(someurl)
    .then((result) => {

      return result.json();
    }).then((jsonResult) => {
      this.canSetState && this.setState({result: jsonResult})
    })
  }

  render(){
    return (
      <Modal
        onOk={() => this.props.toggleVisibility()}
        onCancel={() => this.props.toggleVisibility()}
        visible={this.props.isVisible}
        okText={'ok'}
        cancelText={'cancel'}
        confirmLoading={false}
        title="Intent distribution chart"
      >
        <h1>HOWDY</h1>
        <TreeMap
          data={this.state.result}
          width={400}
          valueUnit={'count'}
        />
      </Modal>
    )
  }
}

答案 1 :(得分:2)

问题是 callApi没有返回任何内容。如果它应该在某处分配数据,则不是。如果确实返回了某些内容,那么它将是一个承诺,因为它是异步的。

您可以使用状态变量并将其映射到data的{​​{1}}道具。然后使用TreeMap生命周期函数在呈现组件后获取数据。一旦响应,用结果更新映射的状态变量。从理论上讲,它应该自动重新呈现componentDidMount