ReactJS 0.14 - 使用承诺

时间:2015-10-18 21:28:30

标签: javascript reactjs

好的,我正在推进我的项目,从组件中的简单数据数组到数据的API调用,并且因为生活中的事情总是存在,组件不再有效。 API正常工作我可以看到数据结果,但它不是在渲染中生成它们:

   // function 
   showMainTestimonial(clientId) {
    let results = [];
    let linkButtonNode = null;
    TestimonyApi.getAll()
        .then(function (data) {
            var data = data.data;

            if (data.showMore) {
                linkButtonNode = (
                    <div style={{ margin:15, width:'100%', textAlign:'center' }}>
                        <Link className="button" to={ data.testimonialsLink }>More Testimonials</Link></div>)
            }

            data.testimonials.map(function (testimony, index) {
                let commenter = null;
                let category = null;

                if (testimony.isMain && results.length === 0) {
                    if (data.showCommenterName) {
                        commenter = (
                            <div style={{ textAlign: 'right', fontSize: 16 }}>
                                <i>-- { testimony.commenter }</i>
                            </div>
                        );
                    }
                    if (testimony.category) {
                        category = (
                            <div style={{ textAlign: 'right', fontSize: 16 }}>
                                <i> { testimony.category }</i>
                            </div>
                        );
                    }

                    results.push(
                        <div id="TestimonialArea" key={ index }>
                            <div className="main" id="TestimonialZone">
                                <div id="TestimonialsFeed" className="NavFeed">
                                    <div className="testspcr"></div>
                                    <article className="lists">
                                        <h3>
                                            "{ testimony.title }"
                                        </h3>
                                        <div className="ReviewText">
                                            "{ testimony.comment }"
                                        </div>
                                        { commenter }
                                        { category }
                                    </article>
                                    { linkButtonNode }
                                </div>
                            </div>
                        </div>
                    )
                    console.log('results from function: ' + JSON.stringify(results))
                    return results;
                }
            });
        }.bind(this))
}
// render
render() {
    let clientId = this.props.clientId;
    var results = this.showMainTestimonial(clientId);
    console.log('render results: ' + results);
    return (
        <section>
            { results }
        </section>
    )
}

enter image description here

正如您所看到的那样,我只是做了一些事情 STUPID

有什么想法吗?

先谢谢。

3 个答案:

答案 0 :(得分:3)

你需要获取promise的结果并将其置于状态,然后让渲染基于状态。

class Foo extends React.Component {
  constructor(){
    super();
    this.state = {data: null};
  }
  fetchTestimonial(clientId) {
    TestimonyApi.getAll()
      .then((x) => this.setState({data: x}))
  }
  render(){
    if (!this.state.data) return <div>Loading</div>
    return (
      <div>
        {this.state.data.map(f)}
      </div>
    )
  }
}

注意:箭头函数很重要,它确保.then回调中this是正确的。仅考虑在方法中使用箭头函数,因为它避免了整个类型的错误。

答案 1 :(得分:1)

TestimonyApi.getAll / promises 异步。对于刚接触JavaScript的人来说,这是一个非常普遍的问题,并且已经被广泛讨论过:

在React的上下文中,数据可能应该是组件状态的一部分。而不是返回results(进入虚空),而是更新状态:

this.setState({results});

这将导致组件重新渲染。在render方法中,请改为访问this.state.results

您可以在安装组件后通过调用方法“自动”开始提取。请参阅Lifecycle Methods中的componentDidMount

仅供参考,render方法永远不应该真正获取数据。在数据发生变化之后,它被称为(因为组件的道具或状态发生了变化)。也许阅读Thinking in React将有助于您更好地理解这一点。

答案 2 :(得分:0)

我弄清楚了我的问题,重构代码使人们更清楚地理解。

基本上,正如FakeRain所说,箭头功能是关键,虽然我想我不适用于普通散文/高海拔理论。无论如何,对于任何其他人都在苦苦挣扎。

当您获取数据,然后计划将其映射到特定的html'片段'时,将获取和映射拆分为2个不同的函数,并记住:

  
      
  1. 在API提取中使用箭头功能; (因为'这个')
  2.   
  3. 调用API函数中的映射函数; (因为API调用是异步的)
  4.   
  5. 绑定映射功能;
  6.   
  7. 将映射结果传递给州。
  8.   

因此,说明性地说:

componentDidMount() {
    this.getAPIData();
}
getAPIData() {
    TestimonyApi.getAll()
        .then((response) => {   <-- don't forget the arrow function
            let data = response.data;
            // call the mapping function inside the API function
            this.showMainTestimonial(data) 
        })
}
showMainTestimonial(data) {
   let results = [];     
   data.map(function(item) {
   // do something with mapped data and push in results
   results.push (

    // customizing the mapping into whatever results you want

    )}.bind(this))  <--- don't forget to bind

  // pass your configured html into state now after mapping
  this.setState({results});
 }