当前位置: 首页 > 知识库问答 >
问题:

React: Warning: setState(...):无法在现有状态转换期间更新

卢雅惠
2023-03-14

当我试图插入一个新的食谱元素时,我的项目总是崩溃。我使用this.state.recipes.map....RecipeList能够根据需要更新食谱(例如删除,编辑等)。
如果我将语句切换到this.props.recipes.map....,我可以插入元素而没有问题,但是由于删除,我无法删除触发状态更改,并需要状态更改来反映更新而不是道具。有人对这个问题有什么建议吗?谢谢!

配方列表:

var RecipeList = React.createClass({
getInitialState: function(){
    return {recipes: []};
},
deleteRecipe: function(recipe){
    var curRecipes = this.state.recipes.slice('');
    curRecipes.splice(recipe.recipeKey,1);
    this.setState({recipes: curRecipes});
},
componentWillMount: function(){
    this.setState({recipes: this.props.recipes});
},
render: function(){

    var recipeNodes = this.state.recipes.map(function(recipe,index){
        return <Recipe onDelete={this.deleteRecipe} recipeKey={index} key={index} recipeTitle={recipe.recipeTitle} ingredients={recipe.ingredients}  instructions={recipe.instructions} />
    },this);
    return(
        <div>
            {recipeNodes}
        </div>
    );
}
});

配方容器:

var RecipeBox = React.createClass({
getInitialState: function(){
    return {showForm: false,
            recipes: []
        };
},
openForm: function(){
    this.setState({showForm: true});
},
handleRecipeSubmit: function(recipe){
    var curRecipes = this.state.recipes.slice('');
    curRecipes.push({recipeTitle: recipe.recipeTitle,ingredients: recipe.ingredients, instructions: recipe.instructions});
    this.setState({recipes: curRecipes});
},
render: function(){
    return(
        <div id="recipeBox">
            <RecipeList recipes={this.state.recipes} />
            <div className="recipeButtons">
                <button id="addRecipeButton" className="btn-style" onClick={this.openForm}>Add Recipe</button>
            </div>
            {this.state.showForm ? this.refs.dialogWithCallBacks.show() : null}
            <SkyLight
                dialogStyles={formDialog}
                ref="dialogWithCallBacks"
                title="Add Recipe">
                <RecipeForm onRecipeSubmit={this.handleRecipeSubmit} skylightRef={this.refs.dialogWithCallBacks} />
            </SkyLight>
        </div>
    );
}
});

配方表:

var RecipeForm = React.createClass({
getInitialState: function(){
    return {hideDialog: false};
},
getFormData: function(){
    var ingredients= document.getElementsByClassName("ingredient"),
        recipeName = document.getElementsByName('recipeName')[0].value,
        instructions = document.querySelector('textarea').value,
        data = [];

    ingredients = [].slice.call(ingredients).map(function(ingredient,index){
        return {
            "quantity": ingredient.childNodes[0].value,
            "ingredient": ingredient.childNodes[1].value,
            "unit": ingredient.childNodes[2].value
        };
    });

    // Combine results into output array
    data.push(recipeName);
    data.push(ingredients);
    data.push(instructions);

    return data;
},
submitRecipe: function(event){
    event.preventDefault();
    var data = this.getFormData();

    // Hide the SkyLight modal container
    this.setState({hideDialog: true});

    // Submit form
    this.props.onRecipeSubmit({recipeTitle: data[0], ingredients: data[1], instructions: data[2]});
},
render: function(){

    return(
        <form onSubmit={this.submitRecipe}>
            <section className="recipe-main">
                <h2 style={{'border-bottom': 'none'}}>Recipe Name</h2>
                <RecipeFormName />
                <h2 style={{'border-bottom': 'none'}}>Ingredients</h2>
                <RecipeFormIngredients />
            </section>
            <RecipeFormInstructions />
            <input type="submit" value="Add Recipe" />
            {this.state.hideDialog ? this.props.skylightRef.hide() : null}
        </form>
    )
}
});

共有2个答案

陆子默
2023-03-14

需要将RecipeList组件更改为

然后从RecipeBox而不是直接在RecipeList中处理删除更改。必须使用this.props.map....来显示新的食谱,并删除可见的食谱。

var RecipeList = React.createClass({
    getInitialState: function(){
        return {recipes: this.props.recipes};
    },
    deleteRecipe: function(recipe){
        var curRecipes = this.props.recipes.slice('');
        curRecipes.splice(recipe.recipeKey,1);
        this.props.onChange({recipes: curRecipes});
    },
    render: function(){

        var recipeNodes = this.props.recipes.map(function(recipe,index){
            return <Recipe onDelete={this.deleteRecipe} recipeKey={index} key={index} recipeName={recipe.recipeName} ingredients={recipe.ingredients}      instructions={recipe.instructions} />
        },this);

        return(
            <div>
                {recipeNodes}
            </div>
        );
    }
});

潘俊楚
2023-03-14

您应该将componentWillMount中的代码移动到getInitialState。

getInitialState: function(){
    return {recipes: this.props.recipes};
},
 类似资料:
  • 无法在现有状态转换期间更新(例如在“呈现”中)。呈现方法应该是道具和状态的纯函数。 我如何修复这种情况,使它将加载项目,并单击链接将重新呈现表单?

  • 我已经创建了以下代码,但是我经常得到以下错误(很多)。看起来应用程序进入了一个循环: 下面是我使用的代码:

  • 我正在开发一个简单的待办事项列表反应应用程序(新的React.js)。我已经将项目添加到工作列表中,但删除项目会引起一个问题。在我的父反应组件中,我有以下代码: 我的组件: 运行此代码将带来: 警告:setState(...):无法在现有状态转换期间更新 问题: 为什么的渲染在添加项时立即执行回调,即: 但是,添加以删除Callback ie。

  • 问题内容: 我正在尝试从渲染视图重构以下代码: 到绑定位于构造函数内的版本。原因是渲染视图中的绑定会给我带来性能问题,尤其是在低端手机上。 我创建了以下代码,但是我不断收到以下错误(很多错误)。该应用似乎陷入了循环: 以下是我使用的代码: 问题答案: 看起来您不小心在render方法中调用了该方法,而您可能想这样做。 如果您不想在onClick处理程序中创建lambda,我认为您将需要两个绑定方法

  • 我正在重写一些旧的ReactJS代码,但在修复此错误时遇到了麻烦(此错误在控制台中重复大约1700次,DOM根本不呈现): 警告:设置状态(…):无法在现有状态转换期间更新(例如在或其他组件的构造函数中)。渲染方法应该是道具和状态的纯函数;构造函数的副作用是一种反模式,但可以移动到。 我是一个组件,它将它的状态传递给一个应该呈现一些控件的组件。基于单击的控件,状态应该更改,并且应该呈现新的控件。