如何禁止在 ES7 函数定义中使用必需参数?

How do I disallow use of a required parameter in a ES7 function definition?

问题

我正在编写一个 ES7 函数,它将由定义参数顺序的 API 调用:

mapStateToProps(state, [ownProps]): stateProps

我需要使用 ownProps 而不是 state。是否可以编写函数定义,以便不指定第一个参数或者任何读取或写入它的尝试都会导致错误("fail fast")?


这不行

这看起来很吸引人,但当然 _ 是一个有效的变量名...:[=​​22=]

function myMapStateToProps(_, ownProps) {
  // ...
}

更多上下文

我的问题真是Skipping optional function parameters in JavaScript的镜像。

我的问题的背景是我正在编写一对 React 组件,它们实现了一个按钮,当它被点击时会执行某些操作。

内部组件指定布局,包括按钮文本,外部组件使模式可见,并使用 react-redux 的 connect 功能与内部组件组合:

function MyButton({ handleOpen }) {
  return (
    <Button onClick={handleOpen} className={s['cta-button']}>
      Button text that I want to configure
    </Button>
  );
}

const mapStateToProps = () => {
  return {};
};

const mapDispatchToProps = (dispatch) => {
  return {
    handleOpen: () => dispatch(doSomeStuff()),
  };
};

const MyButtonContainer = connect(
  mapStateToProps,
  mapDispatchToProps,
)(MyButton);

export default MyButtonContainer;

用法是:

<MyButtonContainer />

我想做的是通过传递给 MyButtonContainer 的 属性 使显示在按钮上的文本可配置:

<MyButtonContainer text="Click me" />

通过使用用于将状态映射到道具的函数的第二个参数 (ownProps) 我可以访问 text 属性,但我仍然不需要任何来自为了清楚起见并减少导致错误的机会,我想编写 mapStateToProps 函数,以便第一个参数不可用。

我正在从 ES7 转译,所以任何标准 ES 都可以。如果有建议的扩展,我也可以使用它们(感谢 webpack)。

或者,如果在 React 中有更好的方法,我也会接受该解决方案。


为什么不把按钮文字放到redux store中呢?

这是一个技术选项。我不喜欢它有几个原因: - 按钮文本是内部组件的 属性,如果我没有使用 HOC 来包装它并提供按钮功能,我会直接将其指定为 属性 - 将它放在 redux store 中是很多编码开销 - 编写 reducers、store initialisers、action creators,必须有更好更简单的方法! - 我想在同一个渲染页面上显示多个按钮,每个按钮都有不同的文本 - 无论我必须在容器上指定什么属性 class,让它成为要显示的文本似乎最干净

如果你想禁止访问一个变量,只需用一个更本地的变量遮蔽它,不要初始化它。

function func1(_, arg) {{
  return 'This works: ' + arg;
  let _;
}}
function func2(_, arg) {{
  return 'This throws: ' + _; // ReferenceError
  let _; // Prevents access to _
}}
console.log(func1(1,2));
console.log(func2(3,4));

参数仍可通过 arguments[0] 访问。

使用_应该没问题。它的意图很明确,不应被明智的开发人员误用。


您可以使用删除第一个参数的 higher-order 函数:

function noState(fn) {
    return (state, ...rest) => fn(...rest); // I'm assuming the `this` context doesn't matter
}

myMapStateToProps = noState(ownProps => {
    …
});