如何清除 React.js 中的状态?

Posted

技术标签:

【中文标题】如何清除 React.js 中的状态?【英文标题】:How can I clear the state in React.js? 【发布时间】:2015-12-01 03:03:42 【问题描述】:

我想我可能在概念上遗漏了一些关于 React 和 Reflux 如何工作的东西。

如果我设置了一个对象(“项目”)的状态,当它呈现到屏幕时(具有其现有属性),我如何使用相同的状态(和存储)来创建一个新项目?

这是我的项目视图中的一些代码:

componentWillMount: function () 

    // We need to get the project based on projectID.
    var projectID = this.props.params.projectID;

    if (projectID) 
        ProjectActions.getProject(projectID);
    
,

这是我的项目商店中的一些代码:

data: ,

listenables: ProjectActions,

getInitialState: function() 
    return this.data;
,

onGetProject: function (projectID) 

    // Get the project based on projectID.
    $.ajax(
        type: 'GET',
        url: '/api/projects/getProject/' + projectID
    ).done(function(response)
        ProjectStore.getProjectSuccessful(response);
    ).error(function(error)
        alert('GET projects failed.');
    );

,

getProjectSuccessful: function(response) 
    for (var prop in response) 
        if (response.hasOwnProperty(prop)) 
            this.data[prop] = response[prop];
        
    
    this.trigger(this.data);
,

然后,假设我点击“新建项目”,我使用以下代码:

mixins: [Reflux.connect(ProjectStore), Router.Navigation],

getInitialState: function () 
    return 
        // Project properties:
        format: '',
        title: '',
        productionCompany: ''

    ;
,

我发现,如果我从商店中删除“getInitialState”,那么在创建新项目时就没有问题。但是,一旦我这样做了,我就不能再编辑我现有的项目,因为没有任何附加到状态(我可以使用 prop 来查看,但这还不够。)

如果我保留“getInitialState”,我会收到错误:

Uncaught Error: Invariant Violation: mergeIntoWithNoDuplicateKeys(): Tried to merge two objects with the same key: `format`. This conflict may be due to a mixin; in particular, this may be caused by two getInitialState() or getDefaultProps() methods returning objects with ***ing keys.

我需要一个只有创建操作的“NewProjectStore”吗?我认为商店可以处理创建、获取、更新等操作。

我错过了什么吗?

【问题讨论】:

您有projects 商店吗?所有项目的数组? 是的,我同时拥有 Projects 商店和 Project 商店。起初我只有Projects,但发现很难在其中的单个项目上使用状态,因为属性会是this.state.project.[property],而React 不能很好地处理它。 【参考方案1】:

当您使用Reflux.connect 时,它会将商店中的getInitialState 添加到您的组件中。这就是为什么您会收到有关重复值的错误。您的答案是使用Reflux.listenTo 或从您的组件中删除getInitialState

第 1 步:在您的商店中修复 getInitialState()

只要您在任何给定时间只拥有一家商店即可。根据您的情况,我建议保留Reflux.connect 并删除组件的getInitialState。一个问题是您商店中的getInitialState 没有组件中声明的默认属性。

第 2 步:修复通量

这并没有错误,因为它确实有效,但是,它没有遵循通量指南。大多数人都同意异步动作属于动作。存储仅存储数据,通常还提供帮助函数以不同方式获取所述数据。试试这个:

更新代码:

var ProjectActions = Reflux.createActions(
    getProject: asyncResult: true
);
ProjectActions.getProject.listen(function (projectID) 
    // Get the project based on projectID.
    $.ajax(
        type: 'GET',
        url: '/api/projects/getProject/' + projectID
    ).done(function(response)
        ProjectActions.getProject.completed(response);
    ).error(function(error)
        alert('GET projects failed.');
        ProjectActions.getProject.failed(error);
    );
);

var ProjectStore = Reflux.createStore(
    init: function () 
        // default project properties:
        this.data = 
            format: '',
            title: '',
            productionCompany: ''
        ;
    ,

    listenables: ProjectActions,

    getInitialState: function() 
        return this.data;
    ,

    onGetProjectCompleted: function(response) 
        for (var prop in response) 
            if (response.hasOwnProperty(prop)) 
                this.data[prop] = response[prop];
            
        
        this.trigger(this.data);
    
);

【讨论】:

您好杰夫,感谢您的回复。我认为你让我走上了正确的轨道,但我可能会遗漏一些东西。我从组件中删除了getInitialState(),并将数据初始化移动到ProjectStore。我现在的问题是,如果我加载一个项目然后尝试创建一个新项目,所有字段都填充有以前加载的项目的值。如何重新调用商店中的getInitialState() 以清除值并将其重置为默认值? 添加一个名为newProject的动作,并在商店中添加一个调用reset的监听器:onNewProject: function() this.init(); 再次感谢您的回复。我应该从哪个函数调用这个新动作?我希望它在调用“渲染”之前成为一个函数 - 因为事实上,我需要在我的 onNewProject 函数中添加一个 this.trigger(this.data) 来触发重新渲染,但我想我不会如果在渲染之前重置了状态,则需要重新渲染。我试过getInitialStategetDefaultPropscomponentWillMount,似乎都是在调用render函数之后。 查看生命周期文档:facebook.github.io/react/docs/component-specs.html。看componentWillMount()componentWillUpdate() 嗯,对我来说,componentWillMount()render() 之前被调用 - 文档提到需要调用 setState() 才能在 render() 之前使用它,我假设设置商店里的数据是一样的。我是否需要从 newProject 操作返回一个值并在组件中设置状态? (奇怪的是,componentWillUpdate() 似乎根本没有被调用。)

以上是关于如何清除 React.js 中的状态?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 React.js 中不使用 onSubmit 清除输入字段

当 React JS 中的一项值使用地图函数中的状态发生变化时,如何动态更新购物车中的值?

React.js/Redux:Reducers 中的 setInterval 和 clearInterval

如何通过链接和路由传递道具/状态 - react.js

如何在 react.js 中的页面加载时显示引导模式?

React.js - 功能组件中的状态未更新[重复]