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
,