在 reactjs 的组件组合中使用 props 的惯用方式是什么

What is the idiomatic way to use props in component composing in reactjs

尊敬的 architects/design 专家,

我正在使用 Alt Js 注入存储和操作以响应本机组件。在这种情况下,一些存储的属性不会在整个组件树中使用,而只会被一些处于更深层次的组件使用。

例如(请参考图片):我使用YZ组件组成了组件X。并将名为 P 的 alt store 注入组件 X 并通过组件 Y 将其作为 prop 传递给组件 Z。在这种情况下,P 商店未被组件 Y 使用,但必须作为道具传递给 Y,因为它需要组件 Z

我觉得组件 Z 的 prop 要求破坏了组件 Y 的使用位置,因为该 prop 实际上并没有被 Y 自己使用,只是传递给Z。在不弄乱代码的情况下注入 alt 存储并将道具传递给子组件的惯用方法是什么。有没有一种方法可以传递 props,将 alt store 注入到一个特定的位置,并在每个组件中使用,而无需通过整个组件树。

你可以通过让每个组件传递它的所有属性来传递意想不到的属性。

function ComponentX(props) {
  const { p } = props;
  // use p here
  return <ComponentY {...props} />;
}

function ComponentY(props) {
  // don't use props.p here
  return <ComponentZ {...props} />;
}

function ComponentZ(props) {
  const { p } = this.props;
  return <span>{p}</span>
}

render(
  <ComponentX p={true} />,
  document.getElementById('app')
);

但是,如果您要通过组件向下传递一个商店,那么您可能想从 react-redux's book and use the context mechanism 中学习。

设计一个用store初始化的provider组件(例子直接来自react-redux)。事实上,您几乎可以肯定只使用 react-redux 来传递您的商店。

export default class Provider extends Component {
  getChildContext() {
    return { store: this.store }
  }
  constructor(props, context) {
    super(props, context)
    this.store = props.store
  }

  render() {
    return Children.only(this.props.children)
  }
}

然后将您的最顶层组件包装在您的提供程序中,所有它(及其子组件)都将能够通过上下文访问商店。

function ComponentX(props, context) {
  const { foo } = context.store;
  return <div>{foo}</div>;
}

render(
  <Provider store={yourStore}>
    <ComponentX />
  </Provider>,
  document.getElementById('app')
);

一般来说,您希望您的组件尽可能地隔离。通过在最顶部编写一个大组件来接收所有 props 并将它们向下传递,您可以将所有组件紧密耦合在一起。

在您的示例中,您的 <Z/> 组件 "depends" 在 <Y/> 组件上,而 "depends" 在 <X/> 组件上连接到商店。

如果你想在其他地方使用你的 <Z/> 组件,你将不得不复制一些类似的层次结构,因为它不是 "standalone" 组件,而是 "component-that-depend-on-some-other-component-higher-connected-to-store" .

我不知道 Alt JS,但在 react-redux 中,这种理念是将您的组件连接到商店,尽可能靠近他们需要数据。任何时候你看到自己传递 props 而不使用这个 props 时,这都是一个很好的指示,表明你应该将你的组件连接到 store。

在你的例子中,你可以这样写:

*(伪代码,我不知道Alt JS):*

<AltJS store={store}>  //let's say AltJs is a component that expose the store via context
    <X>
        <Y>
            <Z p={p received from store}/>
        </Y>
    </X>    
</AltJS/>