Как я должен обрабатывать состояние компонента, следуя единой схеме ответственности - PullRequest
0 голосов
/ 31 мая 2018

Я новичок в ReactJ и пытаюсь следовать передовым методам.Из моего исследования я натолкнулся на пару противоречивых статей, в которых обсуждается, как должна осуществляться реализация.

Должно ли состояние полагаться на свойства, передаваемые из родительского компонента?В приведенных ниже сравнениях они оба следуют SRP, но не уверены, какой из них лучше.Хотелось бы ваш совет, спасибо!

1.- Рекомендации по состоянию компонентов в React.js

Во-первых, и, возможно, самое важное, состояние компонента не должно зависеть от передаваемых реквизитов.(см. ниже пример того, что мы не должны делать)

class UserWidget extends React.Component {
  // ...

  // BAD: set this.state.fullName with values received through props
  constructor (props) {
    this.state = {
      fullName: `${props.firstName} ${props.lastName}`
    };
  }
  // ...
}

2.- 7 архитектурных атрибутов надежного компонента React

Давайте на рефакторинг возьмем одну ответственность: визуализируем поля формы и присоединяем обработчики событий.Он не должен знать, как использовать хранилище напрямую ..... Компонент получает сохраненное входное значение из prop initialValue и сохраняет входное значение с помощью функции prop saveValue (newValue).Эти реквизиты предоставляются с помощью withPersistence () HOC с использованием техники proxy proxy.

class PersistentForm extends Component {  
    constructor(props) {
        super(props);

        this.state = { inputValue: props.initialValue };
    }
    // ...
}

3.- В моем случае у меня есть что-то вроде следующего (интересно, является ли это приемлемой реализацией?) - Должно ли состояние обрабатываться в Tasks или в другом компоненте типа TasksWithPersistence, который находится между TasksWithData и Tasks?

export default function TasksWithData(TasksComponent) {  

    return class withData extends React.Component {
        render() {
            const tasks = TaskAPI.getTasks();
            return (
                <TasksComponent 
                    tasks={tasks} 
                    {...this.props} 
                />
            )
        }
    }

}


export default class Tasks extends React.Component {

    state = { 
        tasks: [], 
        addItemInput: null 
    };

    // ...

    componentDidMount() {
        this.updateComponentState({tasks: this.props.tasks});
    }

    componentDidUpdate() {
        this.prepUIForNextAddition();
    }

    // ...
}

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Суть вашего вопроса, кажется, вращается вокруг анти-паттерна , который должен взять несколько реквизитов и скопировать их в состояние .Это, мутирование реквизита, не является целью государства.Реквизит являются неизменными, обманывая их, государство побеждает этот дизайн.

Цель состояния - управлять вещами, которые являются специфическими для компонента React, то есть строго ограничены только этим компонентом React.Например, переключатель showHide для отображения чего-либо в компоненте React.Думайте о состоянии как о локальной переменной, если это помогает.

Большую часть времени этот антишаблон дублирования реквизита может быть удовлетворен функцией внутри объекта React.Например, ваша переменная state.full_name становится именованной функцией fullName, связанной с компонентом React.(все примеры кода предполагают синтаксис JSX)

Примечание: в JavaScript верблюд является структурой именования функций и переменных, я предполагаю, что вы используете ruby ​​на основе соглашения об именах подчеркивания.ИМО, лучше придерживаться соглашения языка, на котором вы пишете код.Вот почему я использую именование на основе верблюдов.

...
fullName() {
    return this.props.firstName + " " + this.props.lastName
} 
...

Эта функция затем может быть вызвана при рендеринге компонента

# in render() portion of your React component, assuming jsx syntax
<p>Hello, {this.fullName()}</p>

Примечание. Помните, что в ES6вам нужно связать методы вашего класса реакции в конструкторе или использовать синтаксис =>, чтобы их можно было вызывать с помощью этого.

...
constructor(props) {
  super(props);
  this.fullName = this.fullName.bind(this);
}
...

Вы также можете разложитьсоответствующие части нового компонента с именем FullName , если он будет использоваться несколькими компонентами.

<FullName firstName={this.props.firstName} lastName={this.props.lastName} />

Технически, «способ реагирования» - это, по крайней мере, по мнению автора, разложить это на другой компонент для повторного использования.Однако повторное использование компонентов необходимо сопоставлять с добавленной сложностью, то есть не оптимизировать преждевременно.Таким образом, вы можете не захотеть зайти слишком далеко вначале.Время, когда это необходимо, возникнет естественным образом.

Очень широкое обобщение реквизита React заключается в том, что они гарантированы, неизменны и стекают, как водопад, из самого верхнего компонента.Если вам нужно обновить их, обновите их на самом высоком уровне, где это имеет смысл.

В подходе, основанном на простом React, если у вас есть что-то, о чем нужно знать родителю, «поднимите» эту часть кода до родителя и, наоборот, привяжите его к ребенку в качестве подпорки.Например, функция AJAX, которая вызывает API.Я думаю об этом как о попытке сделать компоненты как можно более тупыми .

Родитель становится «источником правды» для предмета, который вы «подняли».Родитель обрабатывает обновления, а затем передает результаты дочерним элементам.Таким образом, в родительском объекте он может существовать как переменная состояния, а затем передаваться как реквизиты дочернему объекту, который затем передает его как реквизиты дочернему объекту и т. Д. Дети обновляются по мере изменения состояния в их родительском объекте, когдаон распространяется вниз по цепочке в качестве реквизита.

Если ваше приложение имеет только React, то есть нет магазинов, которые управляют объектами, такими как в потоковом или избыточном шаблонах, вам, возможно, придется хранить вещи в состоянии самого верхнего объекта, что технически можно было бы считать плохим.По мере того, как ваша система становится все более сложной, эта функциональность будет лучше обрабатываться частями потока или избыточности.

Надеюсь, это поможет!

0 голосов
/ 01 июня 2018

Существует огромная разница между примерами 1 и 2.

В примере # 1 причина, по которой так плохо устанавливать состояние из этих реквизитов, состоит в том, что если реквизиты меняются, виджет не будетОбновить.Лучшие практики или нет, это просто неправильно и плохо в любых рамках.В этом конкретном случае нет смысла даже использовать государство.Одного реквизита будет достаточно.

В примере # 2 реквизит используется только для того, чтобы дать состоянию начальное значение (реквизит даже называется initialValue), подразумевая, что дальнейшие изменения в состоянии будут контролироватьсякомпонент независимо от изменений реквизита.Это не нарушает принцип единственной ответственности за использование реквизита для начального состояния, особенно когда его явно используют для этой цели.

Я действительно не считаю эти два примера противоречивыми, потому что они совершенно разные.Кроме того, в принципе единой ответственности нет правила, согласно которому вы не можете устанавливать состояние из реквизита, вам просто нужно обратить внимание на контекст, в котором вы это делаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...