I am using FlatList to render my list, each list item is clickable; however, when I click the item, it does not work until everything is loaded.
It seems like while the other items are still rendering, you can not perform an action or event until everything is fully loaded.
Here is my code:
return (
<FlatList
refreshing={this.props.refreshLoading}
horizontal={false}
initialNumToRender={20}
maxToRenderPerBatch={20}
showsVerticalScrollIndicator={true}
numColumns={2}
onEndReachedThreshold={0.1}
bounces={true}
keyExtractor={(item) => item}
data={userList}
renderItem={(item) => {
return (
<UserCard
index={item.item[1]}
userInfo={item.item[1]}
contentSize={this.state.contentSize}
navigation={this.props.navigation}/>
)
}}
onEndReached={this.onLoadMore}
onRefresh={this.onRefresh}
/>
);
Is there a proper way to handle it?
This is because the Javascript thread is blocked by the rendering on the screen. Once the render of the batch of rows is complete then it will open up the thread for the click event. This rendering happens in batches, which can be tweaked.
See this issue on Github.
Basically you can play with the initialNumToRender and maxToRenderPerBatch parameters on the list until you get something that works for you, and doesn't look jumpy when rendering (it will render the list incrementally which might look weird if the values are too low - called fill rate).
You can read about these parameters in the react-native docs:
initialNumToRender
maxToRenderPerBatch
Related
I am creating an React project where i am rendering the data by calling the api, and api every time gives me array of data of length 10. i am using react-infinite-scroll-component for using infinite scrolling functionality. i want to load data everytime whenever i scroll at the half part of the screen i don't want to show a loader on my screen. can anybody help me on it.
<InfiniteScroll
dataLength={data.length}
next={fetchMoreData}
hasMore={true}
loader={
<CircularProgress/>
}
>
{data.map((item, index) => {
return <Card data={item} key={index} />;
})}
</InfiniteScroll>
this is my code of infinite scrolling, i tried changing the dataLength props , but it didn't worked.
I think you may want to use the scrollThreshold property as that defines when next will be called.
You can pass a floating point number e.g 0.5 or a string e.g "200px" in order to define this.
If you are looking to remove the loader just omit that prop.
Sourced from list of props here: https://www.npmjs.com/package/react-infinite-scroll-component
I was creating a quiz app using react native. For that I need 10 screens with different questions and options(i.e. same layout. Only questions and options are changed). So for achieving this, is there any method to map through each element of array of questions and display it in each screen respectively ? Or do I need to achieve it manually? š¤ (I am using stack navigator for navigation)
Pass current question number as index when you navigation to question/answers screen - first time pass 0.
Then show question like QuestionArray[index]. And when you want to go to next question just increase index by 1 and push same screen to navigation with index and so on. You can check current index value before pushing the screen to navigation stack that if value is already 9, calculate the result and replace stack with result screen
You can use Flatlist to map through each element
<Flatlist
data={QuizArr}
renderItem={({ Ques, Ans, onNext })=><RenderQuiz {...{ Ques, Ans, onNext }} />}
keyExtractor={item => item.id}
/>
RenderQuiz=({ Ques, Ans, onNext })=>{
return(
// Your Code
)
}
im new to JavaScript & React (and new to stackoverflow too) and I hope to get some ideas/ answers regarding the "logic" in implementing data-storage. I have/ had a dev-background in Obj-C / iOS few years back. So some general concepts in web-dev might not be familiar to me.
Hope I'm doing everything correct in my first post, never really used stackoverflow so far :)
So, basically I have a small project with a Sider und Content (using Ant Design Framework). In this project, im trying to figure out, how generell stuff has to be done, like Navigation through the views, data handling and so on.
In one Tab in the SideBar, i'm using a Table (also antd). If you press on one Item, it should show a detail-View with the props of that specific item (later it should be the form for data change/input).
My App.js:
<Content style=...>
<Switch>
<Route exact path="/tasks" >
<TasksTable
data={this.state.tasksData}
handleOnRowClicked = {this.handleOnRowClicked}
/>
</Route>
<Route exact path="/details">
<TasksDetail currentTask= {this.state.currentDetailTask}/>
</Route>
....
</Switch>
</Content>
In the TasksTable-Component:
...
const history = useHistory()
...
function handleOnRowClicked(record, rowIndex,event) {
console.log("Clicked on cell", event)
history.push("/details/")
props.handleOnRowClicked(record.id)
}
return(
<Table
dataSource={props.data}
onRow={ (record, rowIndex) => {
return {
onClick: event => {
handleOnRowClicked(record, rowIndex,event) }
}
}
}
>
<Column title="Name" dataIndex="name" key="name" />
<Column title="Kunde" dataIndex="client_name" key="client_name" />
<Column title="Fertigstellung bis" dataIndex="completion_date" key="completion_date" />
<Column title="HinzugefĆ¼gt" dataIndex="created" key="created" />
<Column title=""
dataIndex="remove_button"
key="remove_button"
render={removeButton => {
return <button key="ButtonKey" onClick={event => handleOnButtonClicked(event)}>Remove</button>
}}/>
</Table>
)
}
What i want to achive:
When clicked on one row of the table, i want to push another "view"/ Side to show details of selected row. Currently I'm doing this in the TasksTable-Component with history.push(). I'm wondering if this is the correct way of showing (detail-)views? Because I need to call props.myHandleCallbackFunc(selectedItem) in App.js to set a State names "currentlySelected" for then passing this state as prop to the pushed detail view.
Hope you get my point.
As far as I understood, I should use ... for automating the navigation-process. Problem is: As I use the Table from antdesign, I need to make this programatically. Thats why I have this workaround (at least it feels like one) with the onRow property... Is this the correct way of using the table? I have the feeling its not.
Problem with my workaround: I've rendered a Button into the Cells to deliver a delete-Button.
Problem there: Even if i click on the Button, it is registered as a click on the row and therefor pushes my detailview... I tried to differentiate with event.target.key but had no success.
Is it the right way of holding all data fetched by my api in the uppermost component and share it to sup-components via props? How can I update it from subcomponents then? Should every Subcomponent should get a handler via props to call back, when value changed?
Or in other words: Make the http-request from the sub-comp or send the changed data to the App-component and let it then trigger the HTTP-POST-request? I strongly guess its second choice.
Thank you so much, I appreciate every answer. Im trying to get things working since few hours now...
(Sorry for spelling mistakes, english is not my native one).
P.S: Actually I wanted to post this yesterday but took few extra hours for working through the "similar questions"... Still, open questions :D
Robin
Redux is a predictable state container for JavaScript apps.
It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience, such as live code editing combined with a time traveling debugger.
You can use Redux together with React, or with any other view library. It is tiny (2kB, including dependencies), but has a large ecosystem of addons available.
https://redux.js.org/introduction/getting-started
I am trying to get value from the state for materialUI's autocomplete component.
I am facing the following problem : -
Autocomplte working fine for selecting the value and with onChange function it saving it into the state too.
But when I refresh my page/ re-render it is not showing value on the textfeild(from saved state):
<Autocomplete
name={"TideLocation"}
disabled={p.disabled}
options={data_source}
getOptionLabel={option => option.text}
inputValue={this.state.tidelocation_searchtext}
onChange={_this.handleUpdateTideLocationField}
onNewRequest={_this.handleChangeTideLocation}
onBlur={_this.handleBlurTideLocationField}
onUpdateInput={_this.handleUpdateTideLocationField}
renderInput={(params) => (
<TextField className="autoCompleteTxt"{...params} label="Location" />
)}
/>
I tried with the debugger and found its getting value in this.state.tidelocation_searchtext
but failed to set it with params.
Thanks in advance !!
Ps: I tried with defaultValue and search text nothing worked for me
following is my ONchangeFunction
handleUpdateTideLocationField = (str, value) => {
debugger
this.setState({tidelocation_searchtext: value.text});
}
after selecting a value,following value saved in sate :
tidelocation_searchtext: "Auckland"
So I found the solution all by myself by doing research and several hit and try, following is the solution of my problem:
<Autocomplete
name={"TideLocation"}
disabled={p.disabled}
options={data_source.map(option=>option.text)}
defaultValue={this.state.tidelocation_searchtext}
onChange={_this.handleUpdateTideLocationField}
onNewRequest={_this.handleChangeTideLocation}
onBlur={_this.handleBlurTideLocationField}
onUpdateInput={_this.handleUpdateTideLocationField}
renderInput={(params) => (
<TextField className="autoCompleteTxt"{...params} label="Location" />
)}
/>
Basically I was doing the following things wrong :
1.There is no need of using input inputValue={this.state.tidelocation_searchtext}& getOptionLabel={option => option.text}
2.as my data is in object form I have to convert it into a string so default value can match this from the state value
options={data_source.map(option=>option.text)}
Thank you all for your valuable support and solution !!
Removing inputValue has worked for me, even when passing object as options.
Using: "#material-ui/core": "^4.12.3"
If data/state not saved externally f.e. in local storage then it will be lost on page refresh, always. It's normal - like RAM memory without power - it (page/app state) only exists in memory !!
It's like using using cookie to keep you logged in.
If you really need such functionality then use f.e. redux-persist
You are right, if object type options are passed, material-ui's AutoComplete component does not seem to reflect the value when mounted. (Perhaps a bug?)
I was able to get around this by passing the proper characters to inputValue.
#RebelCoder
Maybe you should have initialized tidelocation_searchtext.
For me it was coming from the dropdown z-index which was hidden by another css behaviour.
I added this in a css file :
/* Dropdown MUI Component Autocomplete*/
div[role="presentation"].MuiAutocomplete-popper {
z-index: 1000000;
}
And it appeared finally. A bit hacky, but I think it was caused by another library that had something of that kind.
Note that I added several css elements to the selector, because just using the class wasn't enough.
How do I code this functionality in react-native?
eg. In Instagram when you go to your followers' page, you can view a whole list. You can tap on any of them and you will navigate to that user's specific profile.
I was wondering if it has something to do with React-Navigation like passing some unique id or code, but I am still unclear, please help me out.
P.S I am using cloud firestore from firebase as my database.
The way I would do this is as follows:
1) Create a FlatList:
<FlatList
data={//list of users}
renderItem={this.renderList}
keyExtractor={(item, index) => index.toString()}
/>
2) Every element in the FlatList is a custom component. Navigation props is also passed to the component along with the data. The handler function for renderItem is given below:
renderList = ({ item }) => (
<UserSummary data={item} navigation={this.props.navigation} />
);
3) UserSummary is in fact a Touchable element (say Touchable Opacity) and the onPress event handler for that is given below:
onPress={() =>
props.navigation.navigate("UserDetailsScreen", {
userDetails: props.data
})
Note that I have also passed some data along with the navigation. Let's say, it's some userID that is unique. This information can be used in the UserDetailsScreen to render the details of the user.
Hope this will give you an idea.
you can refer this link. You can pass id as parameter as this.props.navigation.navigate('RouteName', { /* params go here */ }) .