typescript 如何在react中执行双向绑定(子节点发送数据,父节点发送通知)?

t1rydlwq  于 2023-05-01  发布在  TypeScript
关注(0)|答案(1)|浏览(231)

我有一个向导组件,显示下一页和后退按钮。下面是示例:

function Wizard(props){
  return (
    <Grid container>
      <Grid item xs={12}>
        {RenderPage(props)}
      </Grid>
      <Grid item xs={12}>
          <WizardButton title="Back" onClick={previousPage} />
          <WizardButton title="Next" onClick={previousPage} />
      </Grid>
  </Grid>)
}

export function App(props) {
  return (
    <Wizard className='App'>
      <Page>
        <UserInfo />
      </Page>
      <Page>
        <PaymentInfo />
      </Page>
    </Wizard>
  );
}

组件<UserInfo/><PaymentInfo/>具有使用formik实现的它们自己的表单。并且这些部件也用于本申请的其它部分。

我的问题是,我想执行验证的formik尽快下一个按钮被点击。如果验证失败,则向导应停留在当前页面上。如果没有验证错误,则向导应继续。
因此,我需要通知组件执行验证时,下一步按钮被点击。我需要通知向导有关验证结果允许或不允许移动到下一页。
据我所知,这与React的工作原理相反。即父通知子事件,子向父发送数据。
我在尝试几种方法。例如PubSub-js,它使代码变得太复杂,也不是React方式。我也在想,这肯定不是第一次有人遇到这个问题,但我无法找到解决这个问题的方法。

kwvwclae

kwvwclae1#

您可以在Wizard组件中保存一个状态来表示有效性。还可以向子组件传递一个函数,以指示子组件如何通知父组件窗体的有效性状态。
我不知道你的RenderPage函数是什么样子的,但我用渲染 prop 交换了它。你可以根据你的需要调整它。

function Wizard(props){
  const [isValid, setIsValid] = useState(false)

  const setValid = () => setIsValid(true)
  const setInvalid = () => setIsValid(false)

  return (
    <Grid container>
      <Grid item xs={12}>
        {(setValid, setInvalid) => props.children}
      </Grid>
      <Grid item xs={12}>
          <WizardButton title="Back" onClick={previousPage} />
          <WizardButton title="Next" onClick={previousPage} disabled={!isValid} />
      </Grid>
  </Grid>)
}

对于您的子Page组件,您现在可以访问这些有效性状态相关的函数,并将它们传递到相应的表单组件中。

export function App(props) {
  return (
    <Wizard className='App'>
      {(setValid, setInvalid) => (
        <Page>
          <UserInfo setValid={setValid} setInvalid={setInvalid} />
        </Page>
        <Page>
          <PaymentInfo setValid={setValid} setInvalid={setInvalid} />
        </Page>
      )}
    </Wizard>
  );
}

在表单组件内部,每当表单变得有效时,您可以调用setValid,相应地,当它变得无效时,您可以调用setInvalid。然后,Wizard组件中的状态将更改,并且内部的WizardButton组件将被启用/禁用。
如果你希望以另一种方式传递函数,那么Context是另一个选择。

相关问题