异步更新渲染组件 Prop 值

Update Rendered Component Prop Value Async

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

从 fetch 中检索到数据后,如何更新 Sparklines 组件中的道具数据?这可能吗?

这是我的代码示例

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>
       )
     }) 
  }
}

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

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

我会用我自己的组件包装这个组件并接受数据作为道具。
在父组件中,只有当我准备好数据并在每次迭代时将相关数据传递给每个组件时,我才会呈现列表。
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>
    );
  }
}