How to refresh the list when Data changed on Sorting - SwipeListView(react-native-swipe-list-view) - react-native

I am using SwipeListView for Listing with Swipe options
I need to sort the list of Items ascending/descending
Sorting functions are done but the list is not refresh
const [productSortList, setProductSortList] = useState(productArraylist);
productArraylist -> main array list from api
productSortList -> temporary array list to store sorting data
<SwipeListView
//useFlatList={true}
ListEmptyComponent={FlatlistEmpty()}
showsVerticalScrollIndicator={false}
// useNativeDriver={false}
keyExtractor={(item, index) => item.id}
data={productSortList}
renderItem={renderProduct}
renderHiddenItem={renderHiddenItem1}
// leftOpenValue={73}
rightOpenValue={-345}
previewRowKey={productSortList[0].id}
previewOpenValue={-400}
previewOpenDelay={1000}
extraData={productSortList}
// onRowDidOpen={onItemOpen}
/>
In FlatList extraData={Our List Array} will do the refresh when the data get change.
How to do with SwipeListView

Related

How to add filter for getMany() when using ReferenceArrayInput?

I'm using ReferenceArrayInput React Admin.
However, there is issue for me when I selected item from suggestion items that is returned from API getList(). ex:/product?region_id="VN".
Then React Admin auto call API GetMany() with list id, ex: /products?id=1 to get detail item info.
How can customize filter for above API, such as: /products?id=1&region_id="VN" instead
because some product info such as: price, qty,... base on region.
<ReferenceArrayInput
label="Products"
source="product_ids"
reference="products"
allowEmpty={false}
filter={{region_id: record?.region_id}}
fullWidth
filterToQuery={searchText => ({
q: searchText,
})}
>
<AutocompleteArrayInput optionText={optionProductRenderer} validate={required()}/>
</ReferenceArrayInput>

React Native Action Button - Unable to Add buttons Dynamically

Unable to Add ActionButton Items dynamically.
I have the following setup --
<ActionButton>
<ActionButton.item name={constant_btn1} />
<ActionButton.item name={constant_btn2} />
</ActionButton>
I want to add dynamic buttons to this list. (The list is received from backend)
I have created a function that returns me views of these buttons.
getDynamicBtns() {
return dynamicButtonsList.map(item, key) => {(
return <ActionButton.item name={item.btnName} />;
)};
}
and I have used it in this way -->
<ActionButton>
<ActionButton.item name={constant_btn1} />
<ActionButton.item name={constant_btn2} />
{this.getDynamicBtns()}
</ActionButton>
So this is rendering my constant buttons, but not the dynamic buttons.
EDIT -
I am returning the map from the getDynamicBtns() function and calling invoking the function call too from within render(). This is just some simplified sample code that I have wriiten.
EDIT2 -
To prevent any confusion, changing original question's code.
I figured it out.
The problem was that the .map function returns an array of Objects.
So the final element that was going to be rendered was a React element ActionButton.
The ActionButton had only 3 children, irrespective of the size of my dynamic list.
ActionButton.children: [
staticButton1,
staticButton2,
[dynamicButton1, dynamicButton2, dynamicButton3, ....]
];
As a solution, I took them into separate lists and found a union of the lists.
And then rendered the list inside <ActionButton>
Something like this ->
let listA = [<ActionButton.Item name='staticBtn1.name' />];
let listB = this.getDynamicBtns();
let finalList = _.union(listA, listB);
And then rendered it as -->
<ActionButton>
{finalList}
</ActionButton>
You are no returning anything in getDynamicBtns function. You should return the result of your map:
getDynamicBtns() {
return dynamicButtonsList.map(item => <ActionButton.item name={item.btnName} />)
}

React-native - How to create a scrollable flatList in which the chosen item is the one at the middle?

I would like to create a scrollable FlatList to select only one item among a list. After the user scroll the list, the selected item will be the one in the colored rectangle (which have a fixed position) as you can see here :
Actually I'm only able to render a basic FlatList even after some researches.
Do you know how I should do that ?
I found the solution (but it's not a FlatList) !
To do that I use :
https://github.com/veizz/react-native-picker-scrollview.
To define the background of the current selected items I added a new props highLightBackgroundColor in the ScrollPicker Class in the index file of react-native-picker-scrollview :
render(){
...
let highLightBackgroundColor = this.props.highLightBackgroundColor || '#FFFFFF';
...
let highlightStyle = {
...
backgroundColor: highLightBackgroundColor,
};
...
How to use it :
<ScrollPicker
ref={sp => {
this.sp = sp;
}}
dataSource={['a', 'b', 'c', 'd', 'e']}
selectedIndex={0}
itemHeight={50}
wrapperHeight={250}
highLightBackgroundColor={'lightgreen'}
renderItem={(data, index, isSelected) => {
return (
<View>
<Text>{data}</Text>
</View>
);
}}
onValueChange={(data, selectedIndex) => {
//
}}
/>
How it looks without others customizations:
You can implement the same setup with the very popular react-native-snap-carousel package, using the vertical prop. No need to use a smaller, poorly documented/unmaintained package for this.

Rendering sections in flatlist/sectionlist from one data set

I have some JSON data that looks like this:
{
"distance":"1",
"name":"whatever",
"listPriority":"1",
}
I'm passing this into a Flatlist:
<FlatList
key={'my-list'}
data={JSON}
renderItem={this.renderCard}
keyExtractor={(item, index) => index.toString()}
/>
What I want to do is section off the data based on list priority, so all items with a value for listPriority key of 1 would show under my section header that says "These are items for 1", and a value of listPriority key of 2 would have a section header that says "Section header 2", and so forth.
I.e. resulting in something like this:
List Priority 1
item in the list
item in the list
List Priority 2
item in the list
item in the list
List Priority 3
item in the list
item in the list
How can I get sections into my Flatlist?
Sectionlist seems to be only if you are passing in separate data sets for each manually entered section.
It would seem that you could use the SectionList component, that would give you the headers and (if you want) them being sticky, which is a nice to have behaviour.
So you just need to create an array of objects that follow the needed format for the component to work properly.
<SectionList
renderItem={({item}) => someFunctionHere(item)/<SomeComponent item={item}>}
sections={sections}
keyExtractor={(item, index) => index.toString()}
/>
Define sections to be an array of format:
[
{
title: "List priority 1",
data: [{"distance":"1", "listPriority": "1"...}, ...]
},
{
title: "List priority 2",
data: [{"distance":"20", "listPriority": "2"...}, ...]
},
...
]
So again, just format your data (most probably within the componentDidMount hook) and when then data is formatted you can include it into the state and eventually feeding it into the SectionList component so that it will re-render

React Native FlatList with inverted option enabled

I have a FlatList as shown below:
<FlatList
inverted
data={messages}
keyExtractor={this._keyExtractor}
renderItem={({ item }) => (
<Text style={styles.item}>{item}</Text>
)}
onEndReached={this.handleLoadMore}
onEndReachedThreshold={30}
/>
But here the OnEndReached method does not gets called when I reach the top of the flatlist.
Please help
OnEndReachedThreshold must be a number between 0 and 1. Since you are inverting your flatlist, onEndReachedThreshold would be the distance the user is from the top of the list [in percents]. Therefore a value of 0.5 would trigger the OnEndReached function when the user has scrolled through 50% of the viewable list.
To trigger the function at 50% your code should read something like this:
<FlatList
inverted
data={messages}
keyExtractor={this._keyExtractor}
renderItem={({ item }) => (
<Text style={styles.item}>{item}</Text>
)}
onEndReached={this.handleLoadMore}
onEndReachedThreshold={0.5}
/>
All I could figure out was using of onScroll (performance beware) in here: https://snack.expo.io/#zvona/inverted-list-onbeginreached
The actual function looks like this:
checkIfBeginningReached = ({ nativeEvent }) => {
const { layoutMeasurement, contentOffset } = nativeEvent;
const currentPos = layoutMeasurement.height + contentOffset.y;
const listLength = ITEM_HEIGHT * this.state.items.length;
const reactThreshold = listLength - (ITEM_HEIGHT * THRESHOLD);
if (currentPos >= reactThreshold) {
this.fetchMoreItems(this.state.items.length);
}
}
On that, we pick up necessary info from nativeEvent (which kind of holds everything relevant). Then we just calculate the current position in pixels, length of whole list content in pixels and then threshold point.
In all, this particular solution requires two things:
1) list has fixed and same size of elements
2) list is not multi-column.
All the other functionality in the demo is just faking / mimicking one use case (of fetching 50 more items from server with 500ms delay). But I'll improve my answer if possible. But this should get you started.
My solution is here:
isCloseToBottom = ({layoutMeasurement, contentOffset, contentSize}) => {
const paddingToBottom = 1
return layoutMeasurement.height + contentOffset.y >=
contentSize.height - paddingToBottom}
just set onEndReachedThreshold={0.1} or onEndReachedThreshold={0.2}