从子代的数量/类型/属性中提取父代组件配置

时间:2018-07-01 17:56:50

标签: javascript reactjs

在React中是否有从父组件的子组件派生其父组件的配置信息的最佳实践方法?以向导组件为例,该向导组件需要逐步完成一些步骤。您会想象这样的组件的API可能看起来像这样:

<Wizard>
  <Wizard.Step id="step-1" title="It's step 1!">
    Step 1
  </Wizard.Step>
  <Wizard.Step id="step-2" title="It's step 2!">
    Step 2
  </Wizard.Step>
</Wizard>

在上面的示例中,如果您希望向导从步骤1导航到步骤2,则向导将需要某种方式知道它具有两个步骤,并且步骤1位于步骤2之前。使用React.Children.toArray可以遍历每个孩子并像这样读取道具的东西:

const steps = React.Children.toArray(children).map(child => {
  const { id, title } = child.props;
  return { id, title };
});

这在嵌套组件的更复杂的情况下会消失。在向导组件的示例中,您可能希望将某些步骤归为同一标题,如下所示:

<Wizard>
  <Wizard.Heading title="It's steps 1 and 2!">
    <Wizard.Step id="step-1">
      Step 1
    </Wizard.Step>
    <Wizard.Step id="step-2">
      Step 2
    </Wizard.Step>
  </Wizard.Heading>
  <Wizard.Heading title="It's steps 3 and 4!">
    <Wizard.Step id="step-1">
      Step 1
    </Wizard.Step>
    <Wizard.Step id="step-2">
      Step 2
    </Wizard.Step>
  </Wizard.Heading>
</Wizard>

我觉得以前的解决方案在这里失败了。如果您尝试使用先前的方法(使用React.Children.mapReact.Children.toArray)来构建步骤列表,以使向导知道步骤2需要转到步骤3,则会遇到{ {1}}个组件正在更新,而<Wizard.Step />个组件不知道发生了这种事情。

推荐的做法是什么?我可以想到一对可行的方法(例如:让<Wizard />建立一个步骤列表,然后让<Wizard.Heading />仅从标题创建一个步骤列表),但我不确定采用哪种方法使用该代码将在预期使用React的范围内。

或者,这是解决问题的错误方法吗?我是否应该使用大型配置对象来告诉向导它应该如何构造自身?

2 个答案:

答案 0 :(得分:2)

因为这是关于ReactJS编程范例的问题,所以我不会在此处粘贴代码。但是一般的想法是这样的:

道具用于通过组件层次结构向下传递数据,功能用于向上传递数据。因此,如果您想要有关子组件的一些元数据而又不知道子组件可以采用什么形式,则需要将一个函数传递给它们,以访问您的父级状态。

我建议编写一个HOC(特别是this),它将包装您的子组件并将一些附加功能传递给它们,这些功能将通过HOC收集元数据并将其发送给您的父组件。 / p>

要记住的另一件事是context,它也可以在这种情况下使用,其中每个Child都将附加到ComponentDidMount上的上下文,但是上下文带有它自己的issues集,并且应该通常应避免使用,除非必要。

答案 1 :(得分:1)

我认为最好的方法是单个对象,它代表一个向导-一个呈现该向导的组件,它的步骤以及您可能想要显示的任何其他内容(例如标题)。

除了向导的配置外,您还需要在某个地方放置希望从向导中填充的数据。

您需要考虑向导在不同步骤上应显示的所有内容。输入,文字,图像等

const wizard = {
currentStep = 1,
  data: {
    username: '',
    password: '',
    address: '',
},
steps: [
  {
    title: "Basic info",
    inputs: [
      {name: "Username", type: "text", required},
      {name: "Password", type: "password", required},
      {name: "Address", type: "text", required}
     ],
    }
  ]
}

您将拥有一个向导,该向导将执行以下步骤,向其中添加一些常用组件(例如,添加后退/下一步按钮),并将所有输入数据存储到对象中。

<Wizard>
  <Wizard.Step id="step-1" title="It's step 1!">
    Step 1
  </Wizard.Step>
  <Wizard.Step id="step-2" title="It's step 2!">
    Step 2
  </Wizard.Step>
</Wizard>

这里的错误是您试图同时渲染两个步骤。别。只需有一个向导即可知道它正在执行的步骤,然后将步骤对象传递给WizardStep组件。该向导控制可见的步骤,并在状态下对其进行跟踪。