2015-09-04 5 views
4

Я думаю, что мне может быть что-то не так концептуально о том, как работают React и Reflux.Как я могу очистить состояние в React.js?

Если я установил состояние объекта («проект»), когда он отображает экран (с его существующими свойствами), как я могу использовать это же состояние (и хранилище) для создания нового проекта?

Это код с моей точки зрения проекта:

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

Нужен ли мне «NewProjectStore», у которого есть действие для создания? Я подумал, что магазин может обрабатывать создание, получение, обновление и т. Д.

Я что-то упустил?

+0

У вас есть 'projects' магазин? Массив всех проектов? – azium

+0

Да У меня есть магазин 'Projects' и магазин' Project'. Сначала я просто имел «Проекты», но обнаружил, что было сложно использовать состояние в одном проекте внутри него, потому что свойства будут «this.state.project. [Property]», и React не играл хорошо с этим , – Rail24

ответ

3

Когда вы используете Reflux.connect, он добавляетиз магазина в ваш компонент. Вот почему вы получаете ошибку о повторяющихся значениях. Ваш ответ должен либо использовать 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); 
    } 
}); 
+0

Привет, Джефф, спасибо за ответ. Я думаю, что ты меня на правильном пути, но я могу что-то упустить. Я удалил 'getInitialState()' из моего компонента и перевел инициализацию данных в 'ProjectStore'. Моя проблема заключается в том, что, если я загружаю проект, а затем пытаюсь создать новый проект, все поля заполняются ранее загруженными значениями проекта. Как я могу повторно вызвать 'getInitialState()' в хранилище, чтобы очистить значения и сбросить их по умолчанию? – Rail24

+0

Добавьте действие под названием «newProject», а в хранилище добавьте прослушиватель, который вызывает сброс: 'onNewProject: function() {this.init(); } '. –

+0

Еще раз спасибо за ответ. С какой функцией я могу назвать это новое действие? Я хотел бы, чтобы это была функция перед вызовом «render», потому что, поскольку это так, мне нужно добавить 'this.trigger (this.data)' в мою функцию 'onNewProject', чтобы вызвать повторную визуализацию, но Я думаю, что мне не нужно будет повторно отображать, если состояние было сброшено до рендера. Я пробовал 'getInitialState',' getDefaultProps' и 'componentWillMount', все, похоже, после вызова функции render. – Rail24