Javascript 反应提升器:使用scheduleUpdate重新定位

Javascript 反应提升器:使用scheduleUpdate重新定位,javascript,popper.js,react-popper,Javascript,Popper.js,React Popper,我使用在单击按钮后显示日期选择器元素 JSX {({ref})=>( 点击显示 )} {ReactDOM.createPortal( {({ref,style,placement,arrowProps,scheduleUpdate})=>( )} , document.querySelector(“#root”) )} 单击按钮后调用onDateRangeBtnClick时,我想通过调用scheduleUpdate方法来重新定位Popper元素,但我不知道如何实现这一点 如何公开要在OnDa

我使用在单击按钮后显示日期选择器元素

JSX

{({ref})=>(
点击显示
)}
{ReactDOM.createPortal(
{({ref,style,placement,arrowProps,scheduleUpdate})=>(
)}
,
document.querySelector(“#root”)
)}
单击按钮后调用
onDateRangeBtnClick
时,我想通过调用
scheduleUpdate
方法来重新定位Popper元素,但我不知道如何实现这一点


如何公开要在
OnDaterRangeBtclick
中调用的特定
scheduleUpdate
,或者如何有条件地调用函数(
scheduleUpdate
)在JSX本身中?

我会将popper部分拆分为自己的组件,并利用React生命周期挂钩

componentdiddupdate
内部,您可以检查
open
状态是否更改,并相应地触发
scheduleUpdate

// PopperElement.js
export default class PopperElement extends React.Component {
  componentDidUpdate(prevProps) {
    if (this.props.open && this.props.open !== prevProps.open) {
      this.props.scheduleUpdate();
    }
  }

  render() {
    return (
      <div className={`dayPickerOverlay ${this.state.showDatePicker ? "" : "hidden"}`} ref={ref} style={style} data-placement={placement}>
        <DateRangePicker />
      </div>
    );
  }
}

// App.js
<Manager>
  <Reference>
    {({ ref }) => (
      <button ref={ref} onClick={this.onDateRangeBtnClick}>click to show</button>
    )}
  </Reference>
  {ReactDOM.createPortal(
    <Popper placement="auto-end">
      {({ ref, style, placement, arrowProps, scheduleUpdate }) => (
        <PopperElement open={this.state.open} scheduleUpdate={scheduleUpdate} />
      )}
    </Popper>,
    document.querySelector('#root')
  )}
</Manager>

我避免重复
React.createPortal
部分为了简洁起见,它应该取代
YourContent

非常感谢您,先生!React是构建应用程序的可怕方式的另一个很好的例子。只要在状态更改时调用函数,就需要太多不必要的文件和代码。我添加了一种替代方法。您的第一个示例似乎无法工作,因为
ref
无法传递给子组件。你只需要给它起一个不同的名字。比如
innerRef
或者使用react的新forwardRef API,我已经在过去的4个小时里对此进行了修补
// PopperElement.js
export default class PopperElement extends React.Component {
  componentDidUpdate(prevProps) {
    if (this.props.open && this.props.open !== prevProps.open) {
      this.props.scheduleUpdate();
    }
  }

  render() {
    return (
      <div className={`dayPickerOverlay ${this.state.showDatePicker ? "" : "hidden"}`} ref={ref} style={style} data-placement={placement}>
        <DateRangePicker />
      </div>
    );
  }
}

// App.js
<Manager>
  <Reference>
    {({ ref }) => (
      <button ref={ref} onClick={this.onDateRangeBtnClick}>click to show</button>
    )}
  </Reference>
  {ReactDOM.createPortal(
    <Popper placement="auto-end">
      {({ ref, style, placement, arrowProps, scheduleUpdate }) => (
        <PopperElement open={this.state.open} scheduleUpdate={scheduleUpdate} />
      )}
    </Popper>,
    document.querySelector('#root')
  )}
</Manager>
import { Manager, Popper, Reference } from 'react-popper';
import { State } from 'react-powerplug';

const App = () => (
  <Manager>
    <Popper>
      {({ ref, style, scheduleUpdate }) => (
        <State initial={{ open: false }} onChange={scheduleUpdate}>
          {({ state, setState }) => (
            <Fragment>
              <Reference>
                {({ ref }) => (
                  <button
                    ref={ref}
                    onClick={() => setState({ open: true }})
                  >click to show</button>
                )}
              </Reference>
              {open && <YourContent ref={ref} style={style} />}
            </Fragment>
          )}
        </State>
      )}
    </State>
  </Manager>
);