Open eric-om opened 4 years ago
this may help: https://github.com/computerjazz/react-native-draggable-flatlist/issues/186#issuecomment-639654613
note that onRef
returns the react ref, i.e. { current: flatLisRef | null }
and ref.current
will be null
on first render.
Thanks for the response!
So I'm trying to do something like this:
ChildComponent.js:
export default const ChildComponent = ({ myRef }) => {
return (
<DraggableFlatList
onRef={ref => {try {myRef = ref } catch {console.log("Failed to set ref.")}}}
}; />
)};
ParentComponent.js:
import ChildComponent from './ChildComponent';
const ParentComponent = () => {
let myRef;
return (
<View>
<Button onPress={ myRef.current._component.scrollToIndex({ animated: true, index: someIndex }); } />
<ChildComponent myRef={myRef} />
</View>
)
}
I have gotten this to work using your example:
ChildComponent.js:
export default const ChildComponent = () => {
return (
<View>
<Button onPress={ myRef.current._component.scrollToIndex({ animated: true, index: someIndex }); } />
<DraggableFlatList
onRef={ref => {try {myRef = ref } catch {console.log("Failed to set ref.")}}}
}; />
</View
)
};
But I want to be able to call scrollToIndex from ParentComponent. When I try to call it from the ParentComponent it tells me myRef is undefined.
@eric-om were you able to figure out how to do this? I am having the same issue -- having the ref live outside the childComponent with the DraggableFlatList causes it to get set to undefined.
@nicoglennon @eric-om
I'm using it pretty much like this, though Mobx is observable so it might be different with Redux/Context.
class MyComponentList extend React.PureComponent<...> {
draggableListRef: React.RefObject<AnimatedFlatListType<InspectionGroupItem>>;
onDraggableFlatlistRef = (ref: React.RefObject<AnimatedFlatListType<InspectionGroupItem>>) => {
this.draggableListRef = ref;
// Mobx State management
this.props.rootStore.uiStore.setInspectionDraggableFlatlistRef(ref);
// Redux do something else, context as well
...
};
<DraggableFlatlist
onRef={this.onDraggableFlatlistRef}
...
/>
}
In another component:
class MyParentComponent extend React.Component<...> {
onSwitchEditMode = () => {
this.props.rootStore.uiStore.draggableInspectionFlatlistRef.current._component.scrollToIndex({
index: this.props.activeIndex
});
}
}
@nicoglennon @eric-om
I'm using it pretty much like this, though Mobx is observable so it might be different with Redux/Context.
class MyComponentList extend React.PureComponent<...> { draggableListRef: React.RefObject<AnimatedFlatListType<InspectionGroupItem>>; onDraggableFlatlistRef = (ref: React.RefObject<AnimatedFlatListType<InspectionGroupItem>>) => { this.draggableListRef = ref; // Mobx State management this.props.rootStore.uiStore.setInspectionDraggableFlatlistRef(ref); // Redux do something else, context as well ... }; <DraggableFlatlist onRef={this.onDraggableFlatlistRef} ... /> } In another component: class MyParentComponent extend React.Component<...> { onSwitchEditMode = () => { this.props.rootStore.uiStore.draggableInspectionFlatlistRef.current._component.scrollToIndex({ index: this.props.activeIndex }); } }
Good to hear that you got it working for you! I'll try storing it through context and report back. (Will test before end of year for those waiting for on a solution.)
thanks @eric-om, let me know if you need more details.
@nicoglennon @creambyemute I wasn't able to get it to work using hooks/context. I also tried experimenting with rxjs but I couldn't figure out how to observe ref.
Something that I think could work is writing functions in your child component to interact with the flatlist and then exposing those functions through a ref. I wanted to try this but my child component is very complex and this feature isn't worth the re-write at the moment.
@eric-om will give that a try, thanks!
Hello, I am trying to figure this out. I have a functional component but I don't think that should cause a problem.. however..
I tried
const [flatListRef, setFlatListRef] = React.useState(null);
onRef={ref=>{ setFlatListRef(ref); }}
Which said "Warning: Cannot update a component from inside the function body of a different component."
I tried
let flatListRef;
onRef={ref=>{ flatListRef = ref; }}
Which resulted in flatListRef always being undefined (scope is stale).
I tried
const flatListRef =React.useRef(null);
flatListRef = ref;
But flatListRef is a constant so now I can't set it...
I tried
const flatListRef =React.useRef(null);
onRef={flatListRef}
But it says "TypeError: onRef is not a function. (In 'onRef(_this.flatlistRef)', 'onRef' is an instance of Object)"
I tried
const flatListRef =React.useRef(null);
onRef={ref=>flatListRef}
const myFunc= () => {
flatListRef.scrollToEnd({animated: true});
}
But when I call myFunc, it says "TypeError: flatListRef.scrollToEnd is not a function" because flatListRef is just an object that has the property current set to null.
I tried
const flatListRef =React.useRef(null);
ref={flatListRef}
const myFunc= () => {
console.log(flatList);
}
But when I call myFunc it just freezes my app... MMmmkk....
I tried
let flatListRef;
ref={ref=>{ flatListRef = ref; }}
const myFunc= () => {
console.log(flatList);
}
This also froze/crashed my app.
Can someone provide an example of how the variable is defined in a functional component? Or a whole example on Snack would be great too.. <3
@ChrisRArendt I don't understand it myself and would appreciate if someone could educate me here, but if you don't define flatListRef (ie let flatListRef;
) and just use it in onRef={ref=>{ flatListRef = ref; }}
, it should work.
@nicoglennon did that end up working for you?
I was not able to get it working so have moved on. I might return to it if someone finds a workaround!
@eric-om I did what you told me and it works. The problem is, when I save the component and refresh it, onRef is not reloaded, so flatlistRef becomes undefined.
I found a way by useRef. But you probably won't like it.
`
const dragableListContainer = useRef(null);
return (
<Container>
{dragableListContainer === undefined ? undefined : (
<Move
onPress={() => {
dragableListContainer.current.flatlistRef.current._component.scrollToIndex(
{
animated: true,
index: 10,
}
);
}}
/>
)}
<DraggableFlatList
...
ref={dragableListContainer}
....
/>
</Container>
);
`
I would like to expose the flatList ref so that I can call scrollToIndex from another component in my screen. Currently my draggable flat list lives in its own component file and I am able to use the ref within that file with the following code:
onRef={ref => {try {listRef = ref} catch {console.log("Failed to set ref.")}}}
(I am also unsure how listRef gets set because we do not declare it anywhere.)
I'm unable to set the ref to a predeclared variable or to the component's state using the useState hook.