简体   繁体   中英

How can I clear the state in React.js?

I think I may be missing something conceptually about how React and Reflux work.

If I have set the state of an object ("project"), as it renders to the screen (with its existing properties), how can I then use that same state (and store) to create a new project?

This is some code from my project view:

componentWillMount: function () {

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

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

And here is some code from my project store:

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

Then, say I click "new project", I use this code:

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

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

    };
},

What I've found is that if I remove the "getInitialState" from my store, that there is no issue when I go to create a new project. However, once I do that, I can no longer edit my existing project, because there is nothing attached to the state (I can use prop to view but that's not enough.)

If I keep the "getInitialState" I get an error:

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 clashing keys.

Do I need a "NewProjectStore" that only has a create action? I had figured a store could handle create, get, update, etc.

Am I missing something?

When you use Reflux.connect , it adds getInitialState from the store into your component. That would be why you get the error about duplicate values. Your answer is either to use Reflux.listenTo or remove getInitialState from your component.

Step 1: fix getInitialState() in your store

There's nothing wrong with having one store to hold your edit project or new project, as long as you are ok with only having one or the other at any given time. Based on your case, I would suggest keeping Reflux.connect and removing your component's getInitialState . One problem is that getInitialState in your store doesn't have the default properties that are declared in the component.

Step 2: fix your flux flow

This isn't wrong as in that it actually works, however, it's not following the flux guidelines. Most people agree that asynchronous actions belong in the action. The store merely stores data and usually also provides helper functions for getting said data in different ways. Try this:


Updated Code:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM