1

I have this "drop menu" that literally drops from the top using the Matter.js 2d physics engine: https://github.com/NeilSentence/galerie-sens

let world, engine, runner

const { Engine, Runner, World, Bodies, MouseConstraint, Composites, Body } = Matter

class Scene extends React.Component {
    
    constructor(props){
        super(props)
        this.state = {
            removeNonMenuBlocks: this.props.switchsections
        }
    }
    componentDidMount(){
        const runCode = () => {
            // set up all matter.js stuff here (works!).
            // At the bottom, an IIFE called update:
        
            (function update(removeNonMenuBlocks){
                requestAnimationFrame(update)
                // updates CSS positions of DOM elements. works(!)
                // but I need access to the class props here, to dynamically remove 
                // objects from world in real-time, as I do when HTML classes change
                // such as when "delayed-fallable" class is added 
                console.log(removeNonMenuBlocks) 
                // just prints an ever-increasing number
                Engine.update(engine)
            })(this.state.removeNonMenuBlocks)
        }
        run()
    }
}

My intuition is that the ever-increasing number is a good thing because it means something actually updates. But how to get to the juicy state?

The place where the Scene component is used has "parent state" and passes it in via a prop (bool)

switchsections={()=>{return this.state.switchsections}}  

Full project is under src/components/menudrop.js

Neil S3ntence
  • 198
  • 2
  • 19
  • 1
    Calls to `update` made asynchronously by `requestAnimationFrame` will have `removeNonMenuBlocks` undefined. Why do you need to pass a piece of state as a parameter into this IIFE? You can access `this.state` and `this.props` normally from inside of this IIFE--they're in the enclosing scope. That said, this seems like an XY problem--maybe ask about what you're trying to accomplish here rather than the attempted solution. If the issue is basically "how do I integrate MJS into React using the DOM?", maybe [this](https://stackoverflow.com/a/65354225/6243352) will help. – ggorlen Dec 18 '20 at 09:05
  • Thank you for your time & great advice! Funny how now after a couple days of struggling with React & Matter, this link that I had looked at before suddenly makes total sense to me. This was the nudge in the right direction! I think I had inadvertently built everything into this React class component as if I was building without React ;P All I need to do now is HTML element derived sizing with my little getBoundingClientRect(), translate my update logic into this animate function, including the delays etc. – Neil S3ntence Dec 18 '20 at 09:31
  • Maybe it would be best to have matter available at global App scope, if I'm switching on/off physics for disparate HTML elements based on link navigation... – Neil S3ntence Dec 18 '20 at 09:31

1 Answers1

1

state

To answer your question "But how to get to the juicy state?":

You need to bind the this-context, e.g.:

  constructor(props){
    // ...
    this.update = this.update.bind(this);
  }

  update(){
    // ...
    console.log( this.state.removeNonMenuBlocks ); // read the state
    this.setState({ removeNonMenuBlocks: true });  // set the state
    // ...
  }

props

To answer your question "(IIFE) no access to class component's props?":

Same story: You would have access to the component props inside a function that is bound to the components this-context (e.g. inside the update function above).

IIFE

However, in your example code there is no reason to use an IIFE: Here the IIFE is (apparently) intended to encapsulate the state when called the first time, but you want the current state, not an old one.

In fact, it doesn't work in the way it is used there: The update function uses the parameter removeNonMenuBlocks, which is not given by requestAnimationFrame(update).

kca
  • 4,856
  • 1
  • 20
  • 41