Update state to determine if a container is in view











up vote
0
down vote

favorite












I am trying to implement Infinite Scroll in React and I want the URL to change as soon as the one container ends and another one starts.
If I scroll up and view the previous container, URL should change back.



What I did: I have implemented the Infinite Scroll successfully. And am trying to find the position of the container depending on the height of the container and window.scrollY value on page.



I need to update the values in State for that reason and I have used window.onscroll inside render to check for conditions and update the state accordingly.



What is the problem: I am facing issues that I am not getting desired results and I know that I should not be using setState inside render(). But where else can I update the state, if that has to be done depending upon the conditions in window.onscroll that is inside render().



Update



InfiniteScrollingComponent.js



state = {
height: ,
containerThatIsBeingRenderedArr: ,
elementIndex: 0,
upperBound: 0,
lowerBound: null
};

componentDidUpdate = (prevProps, prevState) => {
let urlArr = , height = , containerThatIsBeingRenderedArr = ;
for (let index in this.props.items) {
containerThatIsBeingRenderedArr[index] = document.getElementById(
`${this.props.items[index].slug}`
);
height[index] = containerThatIsBeingRenderedArr[index].offsetHeight;
}
if (prevState.containerThatIsBeingRenderedArr.length === containerThatIsBeingRenderedArr.length) return;
if (containerThatIsBeingRenderedArr.length && height.length) {
this.setState(
{
height: height,
containerThatIsBeingRenderedArr: containerThatIsBeingRenderedArr
}
);
}
};


Then inside render() method, I have:



window.onscroll = () => {
this.changeURL();
}


changeURL method looks like this:



changeURL = () => {
const { elementIndex, height, upperBound, lowerBound } = this.state;
let LB = lowerBound === null ? height[0] : lowerBound;
if (window.scrollY > upperBound && window.scrollY < LB) {
return;
}
if (window.scrollY > LB) {
this.setState(prevState => {
return {
upperBound: prevState.lowerBound,
lowerBound: LB + prevState.height[prevState.elementIndex + 1],
elementIndex: prevState.elementIndex + 1
};
});
}
if (window.scrollY < upperBound) {
this.setState(prevState => {
return {
lowerBound: prevState.upperBound,
upperBound:
prevState.upperBound - prevState.height[prevState.elementIndex - 1],
elementIndex: prevState.elementIndex - 1
};
});
}
};









share|improve this question
























  • can you create an example to show the issue?
    – Priyesh Kumar
    Nov 3 at 14:16










  • A Minimal, Complete, and Verifiable example would be helpful
    – Sagiv b.g
    Nov 3 at 15:46










  • @PriyeshKumar, I have updated the question to include the required code.
    – Kapil Sharma
    Nov 3 at 17:01










  • @Sagivb.g I have updated the question to include the required code.
    – Kapil Sharma
    Nov 3 at 17:01








  • 1




    @KapilSharma it's not a problem. It only called in onscroll event not while rendering so it's not an issue.
    – Daniel Tran
    Nov 4 at 15:50















up vote
0
down vote

favorite












I am trying to implement Infinite Scroll in React and I want the URL to change as soon as the one container ends and another one starts.
If I scroll up and view the previous container, URL should change back.



What I did: I have implemented the Infinite Scroll successfully. And am trying to find the position of the container depending on the height of the container and window.scrollY value on page.



I need to update the values in State for that reason and I have used window.onscroll inside render to check for conditions and update the state accordingly.



What is the problem: I am facing issues that I am not getting desired results and I know that I should not be using setState inside render(). But where else can I update the state, if that has to be done depending upon the conditions in window.onscroll that is inside render().



Update



InfiniteScrollingComponent.js



state = {
height: ,
containerThatIsBeingRenderedArr: ,
elementIndex: 0,
upperBound: 0,
lowerBound: null
};

componentDidUpdate = (prevProps, prevState) => {
let urlArr = , height = , containerThatIsBeingRenderedArr = ;
for (let index in this.props.items) {
containerThatIsBeingRenderedArr[index] = document.getElementById(
`${this.props.items[index].slug}`
);
height[index] = containerThatIsBeingRenderedArr[index].offsetHeight;
}
if (prevState.containerThatIsBeingRenderedArr.length === containerThatIsBeingRenderedArr.length) return;
if (containerThatIsBeingRenderedArr.length && height.length) {
this.setState(
{
height: height,
containerThatIsBeingRenderedArr: containerThatIsBeingRenderedArr
}
);
}
};


Then inside render() method, I have:



window.onscroll = () => {
this.changeURL();
}


changeURL method looks like this:



changeURL = () => {
const { elementIndex, height, upperBound, lowerBound } = this.state;
let LB = lowerBound === null ? height[0] : lowerBound;
if (window.scrollY > upperBound && window.scrollY < LB) {
return;
}
if (window.scrollY > LB) {
this.setState(prevState => {
return {
upperBound: prevState.lowerBound,
lowerBound: LB + prevState.height[prevState.elementIndex + 1],
elementIndex: prevState.elementIndex + 1
};
});
}
if (window.scrollY < upperBound) {
this.setState(prevState => {
return {
lowerBound: prevState.upperBound,
upperBound:
prevState.upperBound - prevState.height[prevState.elementIndex - 1],
elementIndex: prevState.elementIndex - 1
};
});
}
};









share|improve this question
























  • can you create an example to show the issue?
    – Priyesh Kumar
    Nov 3 at 14:16










  • A Minimal, Complete, and Verifiable example would be helpful
    – Sagiv b.g
    Nov 3 at 15:46










  • @PriyeshKumar, I have updated the question to include the required code.
    – Kapil Sharma
    Nov 3 at 17:01










  • @Sagivb.g I have updated the question to include the required code.
    – Kapil Sharma
    Nov 3 at 17:01








  • 1




    @KapilSharma it's not a problem. It only called in onscroll event not while rendering so it's not an issue.
    – Daniel Tran
    Nov 4 at 15:50













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am trying to implement Infinite Scroll in React and I want the URL to change as soon as the one container ends and another one starts.
If I scroll up and view the previous container, URL should change back.



What I did: I have implemented the Infinite Scroll successfully. And am trying to find the position of the container depending on the height of the container and window.scrollY value on page.



I need to update the values in State for that reason and I have used window.onscroll inside render to check for conditions and update the state accordingly.



What is the problem: I am facing issues that I am not getting desired results and I know that I should not be using setState inside render(). But where else can I update the state, if that has to be done depending upon the conditions in window.onscroll that is inside render().



Update



InfiniteScrollingComponent.js



state = {
height: ,
containerThatIsBeingRenderedArr: ,
elementIndex: 0,
upperBound: 0,
lowerBound: null
};

componentDidUpdate = (prevProps, prevState) => {
let urlArr = , height = , containerThatIsBeingRenderedArr = ;
for (let index in this.props.items) {
containerThatIsBeingRenderedArr[index] = document.getElementById(
`${this.props.items[index].slug}`
);
height[index] = containerThatIsBeingRenderedArr[index].offsetHeight;
}
if (prevState.containerThatIsBeingRenderedArr.length === containerThatIsBeingRenderedArr.length) return;
if (containerThatIsBeingRenderedArr.length && height.length) {
this.setState(
{
height: height,
containerThatIsBeingRenderedArr: containerThatIsBeingRenderedArr
}
);
}
};


Then inside render() method, I have:



window.onscroll = () => {
this.changeURL();
}


changeURL method looks like this:



changeURL = () => {
const { elementIndex, height, upperBound, lowerBound } = this.state;
let LB = lowerBound === null ? height[0] : lowerBound;
if (window.scrollY > upperBound && window.scrollY < LB) {
return;
}
if (window.scrollY > LB) {
this.setState(prevState => {
return {
upperBound: prevState.lowerBound,
lowerBound: LB + prevState.height[prevState.elementIndex + 1],
elementIndex: prevState.elementIndex + 1
};
});
}
if (window.scrollY < upperBound) {
this.setState(prevState => {
return {
lowerBound: prevState.upperBound,
upperBound:
prevState.upperBound - prevState.height[prevState.elementIndex - 1],
elementIndex: prevState.elementIndex - 1
};
});
}
};









share|improve this question















I am trying to implement Infinite Scroll in React and I want the URL to change as soon as the one container ends and another one starts.
If I scroll up and view the previous container, URL should change back.



What I did: I have implemented the Infinite Scroll successfully. And am trying to find the position of the container depending on the height of the container and window.scrollY value on page.



I need to update the values in State for that reason and I have used window.onscroll inside render to check for conditions and update the state accordingly.



What is the problem: I am facing issues that I am not getting desired results and I know that I should not be using setState inside render(). But where else can I update the state, if that has to be done depending upon the conditions in window.onscroll that is inside render().



Update



InfiniteScrollingComponent.js



state = {
height: ,
containerThatIsBeingRenderedArr: ,
elementIndex: 0,
upperBound: 0,
lowerBound: null
};

componentDidUpdate = (prevProps, prevState) => {
let urlArr = , height = , containerThatIsBeingRenderedArr = ;
for (let index in this.props.items) {
containerThatIsBeingRenderedArr[index] = document.getElementById(
`${this.props.items[index].slug}`
);
height[index] = containerThatIsBeingRenderedArr[index].offsetHeight;
}
if (prevState.containerThatIsBeingRenderedArr.length === containerThatIsBeingRenderedArr.length) return;
if (containerThatIsBeingRenderedArr.length && height.length) {
this.setState(
{
height: height,
containerThatIsBeingRenderedArr: containerThatIsBeingRenderedArr
}
);
}
};


Then inside render() method, I have:



window.onscroll = () => {
this.changeURL();
}


changeURL method looks like this:



changeURL = () => {
const { elementIndex, height, upperBound, lowerBound } = this.state;
let LB = lowerBound === null ? height[0] : lowerBound;
if (window.scrollY > upperBound && window.scrollY < LB) {
return;
}
if (window.scrollY > LB) {
this.setState(prevState => {
return {
upperBound: prevState.lowerBound,
lowerBound: LB + prevState.height[prevState.elementIndex + 1],
elementIndex: prevState.elementIndex + 1
};
});
}
if (window.scrollY < upperBound) {
this.setState(prevState => {
return {
lowerBound: prevState.upperBound,
upperBound:
prevState.upperBound - prevState.height[prevState.elementIndex - 1],
elementIndex: prevState.elementIndex - 1
};
});
}
};






reactjs






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 10 at 21:52









halfer

14.2k757105




14.2k757105










asked Nov 3 at 14:13









Kapil Sharma

4211




4211












  • can you create an example to show the issue?
    – Priyesh Kumar
    Nov 3 at 14:16










  • A Minimal, Complete, and Verifiable example would be helpful
    – Sagiv b.g
    Nov 3 at 15:46










  • @PriyeshKumar, I have updated the question to include the required code.
    – Kapil Sharma
    Nov 3 at 17:01










  • @Sagivb.g I have updated the question to include the required code.
    – Kapil Sharma
    Nov 3 at 17:01








  • 1




    @KapilSharma it's not a problem. It only called in onscroll event not while rendering so it's not an issue.
    – Daniel Tran
    Nov 4 at 15:50


















  • can you create an example to show the issue?
    – Priyesh Kumar
    Nov 3 at 14:16










  • A Minimal, Complete, and Verifiable example would be helpful
    – Sagiv b.g
    Nov 3 at 15:46










  • @PriyeshKumar, I have updated the question to include the required code.
    – Kapil Sharma
    Nov 3 at 17:01










  • @Sagivb.g I have updated the question to include the required code.
    – Kapil Sharma
    Nov 3 at 17:01








  • 1




    @KapilSharma it's not a problem. It only called in onscroll event not while rendering so it's not an issue.
    – Daniel Tran
    Nov 4 at 15:50
















can you create an example to show the issue?
– Priyesh Kumar
Nov 3 at 14:16




can you create an example to show the issue?
– Priyesh Kumar
Nov 3 at 14:16












A Minimal, Complete, and Verifiable example would be helpful
– Sagiv b.g
Nov 3 at 15:46




A Minimal, Complete, and Verifiable example would be helpful
– Sagiv b.g
Nov 3 at 15:46












@PriyeshKumar, I have updated the question to include the required code.
– Kapil Sharma
Nov 3 at 17:01




@PriyeshKumar, I have updated the question to include the required code.
– Kapil Sharma
Nov 3 at 17:01












@Sagivb.g I have updated the question to include the required code.
– Kapil Sharma
Nov 3 at 17:01






@Sagivb.g I have updated the question to include the required code.
– Kapil Sharma
Nov 3 at 17:01






1




1




@KapilSharma it's not a problem. It only called in onscroll event not while rendering so it's not an issue.
– Daniel Tran
Nov 4 at 15:50




@KapilSharma it's not a problem. It only called in onscroll event not while rendering so it's not an issue.
– Daniel Tran
Nov 4 at 15:50

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53132148%2fupdate-state-to-determine-if-a-container-is-in-view%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53132148%2fupdate-state-to-determine-if-a-container-is-in-view%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Full-time equivalent

さくらももこ

13 indicted, 8 arrested in Calif. drug cartel investigation