Как добавить ссылки на функциональные компоненты с помощью withHandlers в Recompose и вызвать ScrollTo для ScrollView?

Моя конкретная цель — использовать метод ScrollTo ScrollView, но поддерживать структуру функциональных компонентов.

В более общем случае для этого требуется получить ссылку на текущий компонент, который невозможен с голым реагированием.

В декабре 2016 г. recompose добавил позволяет обработчикам свойства withHandlers быть фабричной функцией но я не могу понять, как правильно его использовать.

Как добавить ссылки на функциональные компоненты с помощью withHandlers в Recompose и вызвать ScrollTo для ScrollView?


person GollyJer    schedule 14.08.2017    source источник


Ответы (3)


Вы можете попробовать что-то вроде этого:

/* ... */

const MyView = ({ onRef, children }) => (
    <View>
        <ScrollView ref={onRef} /* ... */>
            {children}
        </ScrollView>
    </View>
)

export default compose(
    withHandlers(() => {
        let myScroll = null;

        return {
            onRef: () => (ref) => (myScroll = ref),
            scrollTo: () => (value) => myScroll.scrollTo(value)
        }
    },
    lifecycle({
        componentDidMount() {
            this.props.scrollTo({ x: 0, y: 100, animated: true })
        }
    })
)(MyView)
person deepsweet    schedule 18.08.2017
comment
это круто. Спасибо! - person GollyJer; 18.08.2017
comment
ага, гениально! - person Jose Browne; 07.05.2018
comment
Я продолжал получать scrollTo, это не функция. Я добавил к нему .root, и это сработало: myScroll.root.scrollTo(value) Не знаю, почему это так... - person Simon; 30.08.2018

Лично я предпочитаю инициировать Ref в качестве опоры.

  withProps(() => ({
    ref: React.createRef(),
  })),

А затем просто передайте его своему компоненту без гражданства

const MyComponent = ({ ref }) => <Foo ref={ref} />
person simPod    schedule 10.10.2018
comment
Как бы вы тогда использовали эту ссылку для прокрутки? - person GollyJer; 10.10.2018
comment
Просто передайте ссылку вашей функции прокрутки. - person simPod; 31.10.2018
comment
Я могу ошибаться, но разве ссылка не воссоздается таким образом при каждом повторном рендеринге? Разве они не должны быть постоянными? - person lukasbalaz7; 18.07.2019

Другой способ — сделать класс хранилищем ссылок:

const Stateless = ({ refs }) => (
  <div>
    <Foo ref={r => refs.store('myFoo', r)} />
    <div onClick={() => refs.myFoo.doSomeStuff()}>
      doSomeStuff
    </div>
  </div>
)

class RefsStore {
  store(name, value) {
    this[name] = value;
  }
}

const enhancer = compose(
  withProps({ refs: new RefsStore() }),
)(Stateless);
person Serge Nikolaev    schedule 22.07.2018
comment
Что ж, верхний ответ намного элегантнее, чем это чудовище, но это другой способ, которым вы можете добиться успеха. - person Serge Nikolaev; 24.07.2018