假设我有一个用于处理应用程序逻辑的容器组件,它有很多方法:
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();
要将方法传递给子组件或上下文提供程序值,您似乎总是不得不执行以下操作(请注意,在本示例中,我根据反应文档)。
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>
);
}
我一直在寻找一种方法来避免一个一个地通过它们。我发现的一个可能的解决方案涉及使用 getter 并循环遍历类实例属性,如下所示:
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
};
如果需要,还可以将 getter 代码提取到实用函数中,以便在其他容器类型的组件中重用。显然,只有当有大量的方法需要传递时,这才是值得的。
它看起来很简单,只要在构造函数中完成就可以正常工作。这有什么疯狂的吗?以任何方式这是不好的做法,还是有任何我不知道的潜在副作用?有没有更好的方法我想念?
编辑
我已经更新了示例以更接近我的真实代码;它现在显示了这些方法可能会做什么样的事情,并使用上下文设置,而不是将方法作为道具传递给单个子组件。