【发布时间】:2019-03-10 03:13:49
【问题描述】:
假设我有一个用于处理应用程序逻辑的容器组件,它有很多方法:
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 documentation 中给出)。
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 代码提取到实用程序函数中,以便在其他容器类型的组件中重用。显然,只有当有大量的方法需要传递时,这才是值得的。
它看起来很简单,只要在构造函数中完成就可以正常工作。这有什么疯狂的吗?以任何方式这是不好的做法,还是有任何我不知道的潜在副作用?有没有更好的方法我错过了?
编辑
我已更新示例以更接近我的真实代码;它现在显示了方法可能做的事情,并使用上下文设置,而不是将方法作为道具传递给单个子组件。
【问题讨论】:
-
我希望您知道,如果您需要将大量方法传递给单个子组件,您的架构很可能存在问题
-
正确的设计应该是“分离关注点”。如果只有子级使用它,则不要在父级中定义函数。最好在子组件中定义它。并且请不要遍历组件来查找功能。我的建议是第一个。而且如果嵌套的children很多,那就试试react redux吧。
-
我在另一个问题上对这个问题有类似的回答,我想我会分享:“在 React 中的组件之间共享功能的正确方法”stackoverflow.com/a/51661103/2430549
-
@DanielHilgarth 我认为你是对的,但我做了一些修改,希望能更好地阐明我的情况。
标签: reactjs class methods getter react-context