在React渲染中循环动态服务器响应

时间:2017-09-11 14:29:28

标签: javascript reactjs promise axios

我正在React中开发一些SPA,我多次遇到过这个问题;我最终以UGLY的方式解决了它,就像下面代码中发布的那样。

我觉得我错过了一些显而易见的东西,但我真的无法找到一种更优雅(甚至是正确)的方法来达到同样的效果,你能帮助我吗?

class Leaderboard extends React.Component {
  constructor(props) {
    super(props);
    this.state={
      lb:{},
      leaderboard:""
    };
    this.leaderboardGet = this.leaderboardGet.bind(this);
    this.leaderboardSet = this.leaderboardSet.bind(this);
    this.lblooper = this.lblooper.bind(this);
    this.lbconstruct = this.lbconstruct.bind(this);
  }


  leaderboardGet(callback){ //server call which returns data
    axiosCall.get('leaderboard.php',{params:{user:this.props.user}})
    .then((response)=>{
      var arr=response.data;
      callback(arr);
    })
    .catch((error)=>{
      console.log(error);
    })
  }
  leaderboardSet(a){ //puts in lb object the results of the server call and calls lb looper
    this.setState({lb: a});
    this.lblooper();
  }
  componentWillMount(){
    this.leaderboardGet(this.leaderboardSet);
  }

  lblooper(){ //the ugliness itself: loops the data in lb object, and pushes it into an "html string" in lblconstruct function 
    Object.entries(this.state.lb).forEach(
      ([key, value]) => this.lbconstruct(`<div class="leaderblock ${value.active}"><div class="leaderscore">${value.pos}) </div><div class="leadername">${value.usrname}</div><div class="leaderscore dx">${value.pts} <i class='fa fa-trophy'></i></div></div>`)
    );
  }
  lbconstruct(s){
    this.setState({leaderboard:this.state.leaderboard+=s});
  }

  render() {
    return (
      <div>
        <div className="leaderboard">
          <div dangerouslySetInnerHTML={{__html:this.state.leaderboard}}/>
        </div>
      </div>
    );
  }
}

基本上,如果我有服务器数据必须放在Html格式的N循环中,我找不到另一种方式,所以我想知道我错在哪里。

1 个答案:

答案 0 :(得分:3)

将数据输出到渲染函数中的react元素:

class Leaderboard extends React.Component {
  constructor(props) {
    super(props);
    this.state={
      leaderboard: {},
    };
  }

  componentWillMount(){
    axiosCall.get('leaderboard.php', { params: { user:this.props.user } })
      .then(response => this.setState({ leaderboard: response.data }))
      .catch(console.log)
  }

  render() {
    const { leaderboard } = this.state
    return (
      <div>
        <div className="leaderboard">
          // .map returns a new array, which we have populated with the react elements
          { Object.keys(leaderboard).map((key) => {
            const value = leaderboard[key]
            return (
              <div key={key} class={`leaderblock ${value.active}`}>
                <div class="leaderscore">{value.pos}</div>
                <div class="leadername">{value.usrname}</div>
                <div class="leaderscore dx">
                  {value.pts}
                  <i class='fa fa-trophy'></i>
                </div>
              </div>
            )
          }) }
        </div>
      </div>
    );
  }
}

这样做是允许反应工作,它可以跟踪那些元素,如果你添加一个,它可以看到差异,只是将一个元素添加到结尾,而不是重新渲染一切。

另请注意,如果您只提取一次数据,则使用&#34;容器&#34;获取数据并将其传递给您的数据的组件#34; dumb&#34;组件作为道具。