1

I am trying to change a variable in react with a callback function but cannot seem to do so. Here is my react component:

const MyComponent = () => {
  let scenePinned;

  const sceneCallback = event => {
    if (event && event.state === 'DURING') {
      console.log('Pinned');
      scenePinned = true;
    } else {
      console.log('Not Pinned');
      scenePinned = false;
    }
  };

  console.log(scenePinned);

  return (
    <div>
      <div style={scenePinned ? 'pinned' : 'not pinned'}/>
      {(progress, event) => (
        //Stuff Happens Here 
      ), sceneCallback(event) )}
    </div>

  );
}

I am using react-scrollmagic and am trying to get the scenePinned variable to change from false to true and back to false again when scene is pinned to top. The console logging of Pinned and Not Pinned is happening correctly but I cannot seem to change the scenePinned variable. I am sure this is something very basic that I am not getting but I cannot understand why this is happening. Any help would be appreciated.

Note: I have tried using state to store the value but the callback is fired on scroll so the maximum depth is exceeded when trying to use state to store the scrolling status.

user3331344
  • 728
  • 8
  • 23
  • Where do you try to access the variable and don't get the correct value? – Yossi Apr 09 '19 at 18:38
  • @Yossi I am trying to console log the variable right under the callback function. The Idea is that I want to control a couple of other elements when the scene is pinned to the top with scrollmagic so I am trying to set a global variable to true or false to be used within the entire component. – user3331344 Apr 09 '19 at 18:41
  • If you want a global variable then use redux. Another way will be to define a state variable in a parent component and set it using a callback, as described in https://stackoverflow.com/a/55555578/5532513 – Yossi Apr 09 '19 at 18:47
  • @Yossi I don't want a global variable for the entire app just for this component so I can use it with a couple of different variables inside of this component. Keep in mind this is going to change on scroll so setting a state variable won't work because it will fire too many times and redux would be unnecessary and redundant for this application. – user3331344 Apr 09 '19 at 18:50
  • Please add all the code that is accessing this variable – Yossi Apr 09 '19 at 18:50
  • @Yossi I have updated the example. I am just trying to see if the scene is pinned so I can control a couple of other div's located in the same component. Like I stated in my comment before. – user3331344 Apr 09 '19 at 18:55
  • See my answer below – Yossi Apr 09 '19 at 19:20
  • i have created a version of you code on the this url https://stackblitz.com/edit/react-4gmmxz i need to know when you are calling this function (progress, event) => { //Stuff Happens Here sceneCallback(event) } so that we can trace this – Mahmoud-Abdelslam Apr 09 '19 at 19:32

3 Answers3

0

You need to use state for this. Otherwise the variable is reinitialized every time the component is rendered, and the value is lost.

ruggierom
  • 99
  • 5
  • Can't use state because this happens on scroll and it is fired to many times and the maximum depth is exceeded because the new value is fired too often. – user3331344 Apr 09 '19 at 18:43
0

console.log(scenePinned);

will run for the first time when the page loads

with react we use state the handle dynamic values. or use rxjs or create your own object and set listeners on it. with some custom event

so ex. with state

state={scenePinned:null}

then inside render method console.log(this.state.scenePinned)

Raj D
  • 485
  • 1
  • 5
  • 11
  • I have stated with the other answer like this state won't work because the callback is fired on scroll so the maximum depth is exceeded when trying to use state. – user3331344 Apr 09 '19 at 18:54
  • then try ...create a claaBack function to the sceneCallback(event, callBack) and use that call back to console.log(scenePinned) – Raj D Apr 09 '19 at 19:00
  • also react setState is an async type function it will have to cover the whole event loop .. may be thats the problem – Raj D Apr 09 '19 at 19:01
  • What good would that do? I need to be able to use the variable in my component. Then end goal is not to just console log the variable it is to use the variable to control other elements in the component. I have updated my question to display this a little better. And state is not an option because the callback is fired too may times and react sets a limit on how often you can set the state – user3331344 Apr 09 '19 at 19:04
  • then inside if else block .. try recursion call to component itself to re-render MyComponent(); – Raj D Apr 09 '19 at 19:18
0
  • A possible solution is to define a state variable in a parent component that will pass it to <MyComponent> as a prop.
  • Them move the sceneCallback function to the parent component and pass it as a prop to <MyComponent>
  • An explanation on how to define such a callback exists in many places. Here is one: (mine... ;) https://stackoverflow.com/a/55555578/5532513
Yossi
  • 5,577
  • 7
  • 41
  • 76