Предположим, у меня есть контейнерный компонент для обработки логики приложения, который имеет много методов:
class ScreenContainer extends React.Component
{
state = {
inputs: { /* various properties for input values */ },
thingyActive: false,
someList: ["thing1", "thing2"],
// ...etc.
};
handleInputChange = e => {
const { name, value } = e.target;
this.setState(prevState => ({
inputs: { ...prevState.inputs, [name]: value }
}));
};
toggleThingy = () => this.setState(prevState => ({
thingyActive: !prevState.thingyActive
}));
coolMethod = () => { /* Do cool stuff */ };
boringMethod = () => { /* Do boring stuff */ };
// ...more methods...
}
Мне нужно, чтобы ВСЕ эти методы были доступны для внутренних компонентов.В этом примере я буду использовать поставщик контекста, и мы просто скажем, что контекст используется различными вложенными презентационными компонентами, составляющими экран в приложении.
const ScreenContext = React.createContext();
Чтобы передать методы либо додочерний компонент или значение поставщика контекста, кажется, что вам всегда приходится делать что-то вроде ниже (обратите внимание, что в этом примере я поднимаю «действия» в состояние в соответствии с рекомендациями, приведенными в документации React ).
class ScreenContainer extends React.Component
{
constructor()
{
super();
this.state = {
// ...same state as before, plus:
actions: {
handleInputChange: this.handleInputChange,
toggleThingy: this.toggleThingy,
coolMethod: this.coolMethod,
boringMethod: this.boringMethod,
everySingleOtherMethod: this.everySingleOtherMethod,
// ...on and on
}
};
}
// ...same methods as before...
render()
{
return (
<ScreenContext.Provider value={this.state}>
{this.props.children}
</ScreenContext.Provider>
);
}
Я искал способ избежать передачи их всех одного за другим.Возможное решение, которое я нашел, включает использование геттера и циклический просмотр свойств экземпляра класса следующим образом:
get allMethods()
{
let output = {};
for (var prop in this)
{
if (this.hasOwnProperty(prop) && typeof this[prop] === "function")
output[prop] = this[prop];
}
return output;
}
Тогда я могу просто сделать:
// (in ScreenContainer constructor)
this.state = {
// ...state,
actions: this.allMethods
};
Код геттера также может быть извлеченв служебную функцию для повторного использования в других компонентах контейнерного типа, если это необходимо.Очевидно, это имеет смысл только в том случае, если нужно передать тонну методов.
Кажется, что это достаточно просто и, кажется, работает просто отлично, пока это делается в конструкторе.Есть ли что-нибудь сумасшедшее по этому поводу?Это плохая практика или есть какие-то потенциальные побочные эффекты, о которых я не знаю?Может быть, есть лучший способ, по которому я скучаю?
РЕДАКТИРОВАТЬ
Я обновил пример, чтобы он был ближе к моему реальному коду;теперь он показывает, что могут делать методы, и использует настройку контекста вместо передачи методов в качестве подпорок к одному дочернему компоненту.