response-popper: переместите с помощью scheduleUpdate - PullRequest
0 голосов
/ 12 сентября 2018

Я использую 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, я хочу изменить положение элемента Поппера, вызывая метод scheduleUpdate, но я не знаю, как к этому подойти.

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

1 Ответ

0 голосов
/ 12 сентября 2018

Я бы разделил поппер часть на ее собственный компонент и использовал бы преимущества крючков жизненного цикла 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.

...