response-popper: переместите с помощью scheduleUpdate

Я использую React-popper, чтобы показать элемент выбора даты после нажатия кнопки.

JSX

<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 }) => (
                <div className={`dayPickerOverlay ${this.state.showDatePicker ? "" : "hidden"}`} ref={ref} style={style} data-placement={placement}>
                    <DateRangePicker />
                </div>
            )}
        </Popper>,
        document.querySelector('#root')
    )}
</Manager>

когда onDateRangeBtnClick вызывается после нажатия кнопки, я хочу изменить положение элемента Popper, вызвав scheduleUpdate метод, но я не знаю, как подойти к этому.

Как я могу раскрыть эту конкретную scheduleUpdate быть вызванным в onDateRangeBtnClick или в качестве альтернативы, как я могу условно вызвать функцию (scheduleUpdate по этому вопросу) в самой JSX?

1 ответ

Решение

Я бы разделил поппер часть на ее собственный компонент и воспользовался преимуществами хитов жизненного цикла React.

внутри componentDidUpdate Вы можете проверить, если 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-powerplug сюда:

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>
);

Я избегал повторять React.createPortal часть для краткости, она должна быть на месте YourContent,

Другие вопросы по тегам