代码之家  ›  专栏  ›  技术社区  ›  Magician

React:在特定父组件下强制子组件

  •  1
  • Magician  · 技术社区  · 7 年前

    <Dialog id="_login" modal={true} onSubmit={() => console.log("x")} onCancel={() => console.log("C")} visible={true} >
        <DialogHead>
            Title Here
        </DialogHead>
        <DialogBody>
            <Field id="username" label="User Name" onChange={(id, value) => { console.log(id, value) }} />
            <Field id="password" label="Password" onChange={(id, value) => { console.log(id, value) }} />
        </DialogBody>
        <DialogFoot>
            <button onClick={e => console.log(e)}>Close</button>
        </DialogFoot>
    </Dialog>
    

    下面是 <Dialog>

    public render() {
        return <div className="hx-dialog-outer" onClick={this.onCancel.bind(this)}>
            <div className="hx-dialog-inner" onClick={(e) => {e.stopPropagation()}}>
                <form name={this.props.id}>
                    {this.props.children}
                </form>
            </div>
        </div>
    }
    

    如何强制父元素下的子元素?我是说, <DialogHead> <DialogBody> <DialogFoot> 应在外部无效 <对话框> 容器。例如,如果像下面这样使用它,它将产生一个错误,如“error:DialogHead必须嵌套在Dialog组件中”

    <div>
        <DialogHead>
            Title Here
        </DialogHead>
    </div>
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   Lux    7 年前

    我想你可以用 安全壳 ,在哪里 对话框 组件将是:

    function Dialog (props) {
      return (
        <div>
          {props.children}
        </div>
      );
    }
    

    <Dialog id="_login" modal={true} onSubmit={() => console.log("x")} onCancel={() => console.log("C")} visible={true} >
        <DialogHead>
            Title Here
        </DialogHead>
        <DialogBody>
            <Field id="username" label="User Name" onChange={(id, value) => { console.log(id, value) }} />
            <Field id="password" label="Password" onChange={(id, value) => { console.log(id, value) }} />
        </DialogBody>
        <DialogFoot>
            <button onClick={e => console.log(e)}>Close</button>
        </DialogFoot>
    </Dialog>
    

    这是参考资料: Containment

        2
  •  0
  •   Allen    7 年前

    React Context API

    // Parent <Dialog/>
    class Dialog extends React.Component {
      static childContextTypes = {
        dialog: PropTypes.object.isRequired
      }
      getChildContext() {
        return {
          dialog: this.props.dialog
        }
      }
    }
    
    // Children <DialogHeader/>, <DialogBody/>, <DialogFooter/>
    const DialogHeader = (props, context) {
      if (context.dialog == null)
        throw new Error('You should not use <DialogHeader/> outside a <Dialog/>')
      // return some markup
    }
    
    DialogHeader.contextTypes = {
      dialog: PropTypes.object.isRequired
    }
    

    自React 16.3以来的新上下文API+

    const {Provider: DialogProvider, Consumer: DialogConsumer} = React.createContext(null)
    
    const Dialog = props =>
      <DialogProvider value={{dialog: props.dialog}}>
        {props.children}
      </DialogProvider>
    
    const DialogHeader = props =>
      <DialogConsumer>
        {({ dialog }) => 
          if (dialog == null) return new Error()
          // return some markup
        }
      </DialogConsumer>