2017-05-19 4 views
1

Also habe ich zwei Komponenten haben ... und ich möchte, dass sie einen nach dem anderen machen ... Der Code ist unterreagieren - Rendering mehrere Komponenten

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")); 

Im Grunde ist es ein Rezept Titel nach einem Rezept folgen. Das Problem ist, wenn ich ein paar machen, was passiert, ist, dass alle Titel gehen zusammen und nicht mit jedem Rezept zB ... ich es so will ..

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 

Wie kann ich sie zusammen machen? Wenn Sie mehr Code oder Klärung benötigen, lassen Sie es mich wissen. Irgendwelche Vorschläge, um Code zu verbessern? Wenn es zu lange zum Lesen ist, lass es mich auch wissen. Danke,

+0

Sie möchten die gleichen Rezepte für alle rezeptTeile gerendert werden? Können Sie das Array und mehr Code dieser beiden Funktionen anzeigen? –

+0

Warum haben Sie Ihre Daten trotzdem getrennt? Es wäre viel sauberer, die Titel mit den Rezepten zu behalten, da ein Titel Teil des Gesamtrezepts ist. Anstatt mit Ihrer Dual-Array-Struktur herumzuhacken, reparieren Sie Ihre Daten und haben eine '' Komponente, die den Titel und das Rezept rendert. –

+0

Danke Dave. Ich werde das später versuchen –

Antwort

0

Sie müssen die beiden Listen abstimmen. Angenommen recipeTiles hat eine Eigenschaft von recipe_id und recipe hat eine Eigenschaft von id. Sie können einfach so etwas tun:

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

Verwenden Sie einfach eine altmodische Schleife. Statt dessen:

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

Sie könnten z.B. tun Sie dies:

0

Sie wollen jedes Rezept mit einem Rezept Titel zuordnen und dann zusammen rendern. Ihre Render-Methode sollte ein bisschen wie folgt aussehen:

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

 
}

0

Sie können nur die Rezepte zugreifen Rezept Array durch den Index, wenn sie durch das Rezept Array iterieren

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

I Ich weiß nicht, wie deine Daten aussehen. Also nehme ich an die beiden Zustände Daten wie diese

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

Dann in Ihrer Render-Funktion, können Sie einfach eine Schleife durch sie wie

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

Es ist einfach, so dass Sie die Idee leicht zu bekommen. Sie können dem Tag <p> className hinzufügen, falls Sie ihn mit Stylesheets anpassen möchten.