React count up on scroll - javascript

I'm using react-countup plugin to animate a counter from 0 to identified number and i wanted to make this counter works only once on scroll when it's revealed first time..
and I used this code using react visibility censor
<CountUp start={0} end={4.8} duration={2} decimals={1}>
{({ countUpRef, start }) => (
<VisibilitySensor onChange={start}>
<span ref={countUpRef} />
</VisibilitySensor>
)}
</CountUp>
but then it's happening every time it's revealed in the page and i want it to happen only the first time

why don't you try setting a variable to local storage that you reference if viewedOnce is true or false localStorage

Related

Resetting state of a component in ReactJs by changing its position in the UI tree

React will keep the state around for as long as you render the same component at the same position
in this example, I render 2 Counter components, by checking the checkbox, I control showing/hiding the first Counter component.
export default function App() {
const [showA, setShowA] = useState(true);
return (
<div>
{showA && <Counter />}
<Counter />
<label>
<input
type="checkbox"
checked={showA}
onChange={e => {
setShowA(e.target.checked)
}}
/>
Render the first counter
</label>
</div>
);
}
based on the docs, ** React keeps track of which state belongs to which component based on their place in the UI tree. You can control when to preserve state and when to reset it between re-renders.**
so when I hide/then show the first Counter, its state gets reset, the question is, by hiding and showing the first counter, we are changing the position of the second counter, yet its state doesn't get reset, any help why?
I expected that since the position of the 2nd component changes, then its state will reset as well, yet that did not happen
According to Javascript docs:
operator returns the value of the first falsy operand encountered when
evaluating from left to right, or the value of the last operand if
they are all truthy
I am no expert in Javascript / React JS, but I believe your react UI tree holds values below:
first position: false or <Counter />
second position: always <Counter />
Hence, your second <Counter />'s state will not reset.

changing selected state of fetched item from API

I have an API that returns me arrays. I implemented the code to search 3 of them like this:
{response !== undefined &&
search !== "" &&
response.InsuranceServiceList.filter((insurance) =>
insurance.Name.replace(/ي/g, "ی", /ا/, "آ").includes(search)
)
.slice(0, 3)
.map((filtered, i) => (
<EachInsurance
filtered={filtered}
key={i}
styles={scss}
DatePresence={DatePresence}
IdInsurance={IdInsurance}
TimePresence={TimePresence}
/>
))}
whenever user types something in search box, 3 of these matching arrays will get rendered.
but I have two problems with selecting them.
this is each insurance component:
<Container
className={styles.eachInsurance}
style={{
borderRight: `${selectInsurance ? "20px" : "1px"} solid #fcc4de`,
}}
>
<div
onClick={() => {
setSelectInsurance((prev) => !prev);
setCount(0);
}}
>
<p className={styles.NameService}>{filtered.Name.replace(/ي/g, "ی")}</p>
</div>
</Container>
whenever user clicks on element. it will have pinkish border with the width of 20px.
the problem is, when I type another thing to search another item. it shows that Item selected.
just like the clicked div is still there but the content inside of it has changed.
how can I prevent this problem?
I thought it would render a new div per each array. but it wasn't.
the second problem is search itself. if you delete what you've write completely (emptying search bar). everything you have selected before will get removed and you will need to reselect it again.
I want to prevent this too.
You need to pass the id from your back end to your front end. then add a border based on the ids you pass to the selectInsurance, in that way you will know if the element change the border will be gone.
I think for your second problem you can add a new state that will reserve the whole object of the insurance and you first render from that array so every time you re-render your search array your selected insurance array will stay the same so they will remain in your page

i want my react component to load more data when i scroll to half of my screen

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

Is there a method to map screens

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
)
}

Material UI Autocomplete component not showing values from react state

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.

Categories

Resources