更新渲染组件道具值异步

问题描述 投票:1回答:2

我用财务数据创建了几个列表项,我想用react-sparklines在侧面显示一个迷你图。因此,我在映射数组时尝试获取图形数据,因为检索数据可能需要一些时间,但似乎我无法使图形组件正确更新prop值。

一旦从fetch中获取数据后,如何更新Sparklines组件中的prop数据?是否可能?

这是我的代码示例

class CurrencyList  extends Component {

  currencyGraph(symbol) {
     return fetch(baseURL, {
        method: 'POST',
        headers: {
            'Authorization': 'JWT ' + token || undefined, // will throw an error if no login
        },
        body: JSON.stringify({'symbol': symbol})
    })
    .then(handleApiErrors)
    .then(response => response.json())
    .then(function(res){
        if (res.status === "error") {
            var error = new Error(res.message)
            error.response = res.message
            throw error
        }
        return res.graph_data
    })
    .catch((error) => {throw error})
  }

  render () {
     topCurrencies.map((currency,i) => {
       return (
         <ListItem key={i} button>
           <Sparklines data={this.currencyGraph(currency.symbol)} >
             <SparklinesLine style={{ stroke: "white", fill: "none" }} />
           </Sparklines>
           <ListItemText primary={currency.symbol} />
         </ListItem>
       )
     }) 
  }
}
reactjs sparklines
2个回答
0
投票

您不能从这样的异步函数返回数据。相反,当您的加载请求完成时,将数据设置为将触发组件呈现的状态。请注意,在下面的测试用例中,它会呈现占位符,直到数据准备就绪。

Item = props => <div>{props.name}</div>;

class Test extends React.Component {
  state = {
    data: ''
  }

  componentDidMount() {
    // Simulate a remote call
    setTimeout(() => {
        this.setState({
          data: 'Hi there'
        });
    }, 1000);
  }

  render() {
    const { data } = this.state;
    return data ? <Item name={this.state.data} /> : <div>Not ready yet</div>;
  }
}

ReactDOM.render(
  <Test />,
  document.getElementById('container')
);

Fiddle


1
投票

我将使用我自己的组件包装此组件并将数据作为props接受。 在父组件中,我将仅在我准备好数据时呈现列表,并在每次迭代时为每个组件传递相关数据。 Here is a running small example

const list = [
  {
    key: 1,
    data: [5, 10, 5, 20]
  },
  {
    key: 2,
    data: [15, 20, 5, 50]
  },
  {
    key: 3,
    data: [1, 3, 5, 8]
  }
];

class MySparklines extends React.Component {

  render() {
    const { data } = this.props;
    return (
      <Sparklines data={data} limit={5} height={20}>
        <SparklinesLine style={{ fill: "#41c3f9" }} />
      </Sparklines>
    );
  }
}

class App extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      dataList: []
    }
  }

  componentDidMount() {
    setTimeout(() => {
      this.setState({ dataList: list });
    }, 1500);
  }

  renderCharts = () => {
    const { dataList } = this.state;
    return dataList.map((d) => {
      return(
        <MySparklines key={d.key} data={d.data} />
      );
    })
  }

  render() {
    const { dataList } = this.state;
    return (
      <div>
      {
        dataList.length > 0 ?
        this.renderCharts() :
        <div>Loading...</div>
      }
      </div>
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.