У меня есть приложение React, которое асинхронно получает info с методом getInitialInfo
.MessageView
является самым верхним компонентом, поэтому Данные должны жить в своем состоянии, даже если оно не изменится.В идеальном мире IMessageInfo
будет проходить через реквизиты .
Нам нужно export
типа IMessageInfo
, потому что есть код, который зависит от этого интерфейса .
ВАРИАНТ 1 - (Плоское решение без частного состояния)
import * as React from 'react';
import Message from './Message';
// IMessageInfo needs to be exported because there is code that depends on it
export interface IMessageInfo {
message: string;
icon: string;
}
export interface IMessageViewProps {
getInitialInfo(): Promise<IMessageInfo>;
}
// MessagesView is the upper most Component
class MessageView extends React.Component<IMessageViewProps, IMessageInfo> {
constructor(props) {
super(props);
this.state = {
message: '',
icon: ''
};
this.getInitialInfo();
}
private async getInitialInfo(): void{
let info = await this.props.getInitialInfo();
this.setState(info);
}
render(): JSX.Element {
// Message is reusable component that receives the info through `props`
return <Message {...this.state} />);
}
}
С точки зрения проектирования React State
должно быть личное к компоненту.Я согласен с этим.Но здесь вся информация о состоянии Public .Что может бросить эту концепцию пути.(Если, например, DATA всегда ведется в докладчике, почему в этом случае он должен быть закрытым?)
OPTION 2 - (Плоское решениеИмея частный реплицированный интерфейс для State)
Говоря с некоторыми коллегами, они утверждают, что мы всегда должны сохранять состояние приватным.Я сразу подумал о создании IMessageViewState
, который будет точно таким же, как IMessageInfo
.Таким образом, концептуально все будет правильно, но мы получим проблему с обслуживанием (IMessageInfo
и IMessageViewState
для обновления при изменении некоторых его членов).
ОПЦИЯ 3 -(Составьте IMessageInfo в IMessageViewState. Имеет личное состояние)
Итак, мои коллеги предложили определить IMessageViewState
как:
interface IMessageViewState {
messageInfo: IMessageInfo;
}
Таким образом, мы предпочитаем состав (они говорят).Но я не вижу никакого преимущества в том, чтобы иметь здесь композицию.Вы видите что-нибудь?Например, если какой-либо член IMessageInfo
изменится (сообщение или значок), нам нужно будет передать весь объект messageInfo
в this.setState(...)
, вместо того, чтобы, например, только обновить icon
.По сути, это была бы более подверженная ошибкам реализация.
OPTION 4 - (Расширение IMessageInfo. Имеет частное состояние)
Я также думал о том, чтобы иметьIMessageViewState
расширение IMessageInfo
.Кажется, лучшее решение для достижения состояния, которое не экспортируется.Но мои коллеги сказали, что это не очень хорошее решение, потому что мы отдаем приоритет наследованию над композицией.
Я думаю, что наследование здесь не дает возврата.
ЗАКЛЮЧЕНИЕ
На мой взгляд, опция 1 - это то, что лучше всего подходит для этой проблемы.Поскольку все члены государства являются публичными, я думаю, что нет необходимости иметь частное государство.Опция 1 обеспечивает чистоту кода.
Хотя, если бы я выбрал решение с частным состоянием, лучше подойдет Вариант 4 .
ВОПРОС: Какое решение будетбыть правильнее?