反应 - 渲染多个组件

时间:2017-05-19 13:02:34

标签: reactjs

所以我有两个组件......我希望它们一个接一个地渲染......代码在下面

 var Recipe = React.createClass({

  getInitialState: function(){
    return {editing:false},
   {titles: []}
  },

  edit: function (){
    this.setState({editing:true});
  },


  remove: function(){
    this.props.deleteFromBoard(this.props.index)
  },
  save: function (){

    this.props.updateRecipeText(this.refs.newText.value,this.props.index)
        this.setState({editing:false});

  },


    renderNormal: function() {
    return (
      <div className="recipeContainer">
        <div>{this.props.children}</div>
        <button onClick ={this.edit} className ="button-primary">Edit</button>
        <button onClick ={this.remove} className ="button-remove">Remove</button>
</div>

    );
  },
  renderForm: function() {
    return (
      <div className="recipeContainer">
        <textArea ref="newText" defaultValue ={this.props.children}></textArea>
        <button onClick ={this.save} className ="button-danger">Save</button>
</div>

    );
  },






  render: function() {
    if(this.state.editing){
      return this.renderForm();
  }

    else{
      return this.renderNormal();
    }

  }
});

var RecipeTitle = React.createClass({
    getInitialState: function(){
    return {editingTitle:false}
  },
    edit: function (){
    this.setState({editingTitle:true});
  },



  remove: function(){
    this.props.deleteFromBoard(this.props.index)
  },
  save: function (){

   this.props.updateTitle(this.refs.newTextTitle.value,this.props.index)
        this.setState({editingTitle:false});

  },


  renderTitleNormal: function(){
    return(
          <div>   

    <h2>{this.props.children}</h2>
        <button onClick = {this.edit}>Edit</button> 
</div>
      )
  },
      renderTitleForm: function() {
    return (
      <div>   

                <textArea ref="newTextTitle" ></textArea>
        <button onClick ={this.save} className ="button-danger">Save</button>


</div>

    );
  },

    render: function() {

    if(this.state.editingTitle){
      return this.renderTitleForm();


  }  else{
return this.renderTitleNormal();  

  }
    }
});



var Board = React.createClass({
  getInitialState: function () {

    return {
      recipes: [
      ],
   titles: [

   ]
    } 

  },
  add: function(text,title){
        var arr = this.state.recipes;
arr.push(text);
    this.setState({recipes: arr})
    var arrTitle = this.state.titles;
    arrTitle.push("Title");
    this.setState({titles: arrTitle})
  },


  removeRecipe: function (i) {
    var arr = this.state.recipes;
    console.log(arr);
    arr.splice(i,1);
    this.setState({recipes: arr})
  },
    removeTitle: function (i) {
    var arr = this.state.titles;
    arr.splice(i,1);
    this.setState({titles: arr})
  },
  updateRecipe: function (newText, i) {
    var arr = this.state.recipes;
    arr[i]=newText;
        this.setState({recipes: arr})

  },
eachTitle: function (title, i){
return (<div><RecipeTitle key={i} index={i} updateTitleText={this.updateTitle} >{title}</RecipeTitle></div>);                  
      },


  updateTitleText: function (newTitle, i) {
    var arr = this.state.titles;
    arr[i]=newTitle;
        this.setState({titles: arr})

  },

  eachRecipe:

 function (text, i){
return (<div><Recipe key={i} index={i}  updateRecipeText={this.updateRecipe} deleteFromBoard={this.removeRecipe}>{text}</Recipe></div>);                  
      },
  eachTitle:

 function (title, i){
return (<div><RecipeTitle key={i} index={i} updateTitle ={this.updateTitleText} deleteFromBoard={this.removeRecipe}>{title}</RecipeTitle></div>);                  
      },


   render: function () {
  return(
    <div>
      <button onClick={this.add.bind(null,'Default Text')}>Add New</button>
  <div >
    {this.state.titles.map(this.eachTitle)}

    {this.state.recipes.map(this.eachRecipe)}


  </div>
      </div>
  );
}
});


ReactDOM.render(<Board />
, document.getElementById("app"));

基本上它的食谱标题后跟食谱。问题是,一旦我渲染了一些所发生的事情,所有的标题都在一起,而不是每个食谱,例如...... 我想要这样...... ..

Chicken Reicpe
Recipe here

Beef Recipe
Recipe Here

Cococnut Recipe
Recipe here

Instead its like this.

Chicken Recipe
Beef Recipe
Coconut Recipe

Recipe
Recipe
Recipe

如何将它们组合在一起?如果您需要更多代码或澄清,请告诉我。有什么改进代码的建议吗?如果阅读时间太长,请告诉我。 谢谢,

5 个答案:

答案 0 :(得分:1)

我不知道您的数据是什么样的。所以我想两个状态数据看起来像这样

repTitles: [{
        text: 'chicken'
    }, {
        text: 'beef'
    }],
repFormulars: [{
        text: 'chicken-rep'
    }, {
        text: 'beef-rep'
    }]

然后在你的渲染函数中,你可以像

一样循环遍历它
render: function() {
    return (
        <div>
            {this.state.repTitles.map((title, idx) => {
                return (
                    <div>
                        <p>{title.text}</p>
                        <p>{this.state.repFormulars[idx].text}</p>
                    </div>
                );
            })}
        </div>
    );
}

它很简单,所以你可以很容易地得到这个想法。您可以将className添加到<p>标记,以防您想使用样式表对其进行自定义。

答案 1 :(得分:0)

您必须协调这两个列表。假设recipeTiles的属性为recipe_id,而recipe的属性为id。你可以简单地做这样的事情:

renderRecipes() {
  const { recipes, recipeTiles } = this.props;
  recipes.map(recipe => {
    const tile = recipeTiles.find(({ recipe_id }) => recipe_id === recipe.id);
    return (
      <div>
        <RecipeTile {...tile} />
        <Recipe {...recipe} />
      </div>
    );
  }))
}

答案 2 :(得分:0)

只需使用旧式循环。而不是:

render() {
  return (
    <div>
      {this.state.recipeTiles.map(this.eachTitle)}
      {this.state.recipes.map(this.eachRecipe)}
    </div>
  );
}

你可以,例如这样做:

render() {
  const result = [];
  const { recipeTiles, recipes } = this.state;
  for(let i = 0; i < recipeTiles.length; i++) {
    result.push(this.eachTitle(recipeTiles[i]));
    result.push(this.eachRecipe(recipes[i]));
  }
  return (
    <div>
      {result}
    </div>
  );
}

答案 3 :(得分:0)

您需要将每个食谱与食谱标题相关联,然后将它们一起渲染。您的渲染方法应该如下所示:

render(){

  // This gives us a container that has recipe and title properties
  const recipeContainers = this.state.recipes.map( (recipe, index) => {
    const title = this.state.recipeTiles[index]
    return {
      title,
      recipe
    }
  })

  // Now that we have the info bundled together, we can spit it out on the page
  return (
    <div>
      {recipeContainers.map( ({recipe, title}) => (
      <dl>
        <dt>{this.eachTitle(title)}</dt>
        <dd>{this.eachRecipe(recipe)}</dt>
      </dl>
      )
    </div>
  )

}

答案 4 :(得分:0)

在迭代配方数组

时,您可以通过索引访问配方数组中的配方
render(){
    var recipe = [...this.state.recipe];
    return(
       <div>
           {this.state.recipeTiles.map((title, index) => {
                   return (
                          <div key={index}>
                               <div>{title}</div>
                               <div>{recipe[index]}</div>
                          </div>

                   )
            });
       </div>
    )
}