Badrush
Badrush

Reputation: 1287

How to call nested react function

Objective: When my Game component receives a prop I want componentDidUpdate() to call a function called consolelog which is a child of another function called gamecode().

Problem: using this.gameCode.consolelog() always returns an error saying that consolelog is not a function of gameCode.

Note: Gamecode() is imported into my react component (Game) from a file called gamecode.js

Component:

import React, {Component} from 'react';

import {gameCode, showLeaderboard} from '../utility/gamecode';

class Game extends Component{
  constructor(props){
    super();
    this.state = {
      drawL : null
    }
  };

  componentDidMount(){
    this.gameCode();
  };

  componentDidUpdate(){
    //will run when the state changes
    if(this.props.leaderboard){
        var a = this.props.leaderboard;
        this.gameCode.consolelog(a);
    }
  }   

  render(){
    return(
      <div className="Game">
        <canvas id="canvas"></canvas>
        <button onClick={this.props.getleaderboard} className="showleaders">Show leaderboard</button>
      </div>
    );
  }
}

export default Game;

GameCode.js function:

gameCode(){
  //the main function initializes some stuff immediately and start running the update() and draw() functions
  const canvas = document.getElementById('canvas');
  canvas.width = 800;
  canvas.height= 600;
  const ctx = canvas.getContext("2d");
  const FPS = 30;
  setInterval(() => {
      update();
      draw();
  }, 1000/FPS);

  //but sometimes I need to call other functions on demand, but these functions depend on what the parent function and other sibling functions
  function consolelog(a){
    console.log("success!");
    console.log(a);
  }
}

Upvotes: 0

Views: 7423

Answers (3)

Andy
Andy

Reputation: 63524

You could use something along the lines of a revealing module pattern. Keep private variables in scope to gameCode and export the public vars and functions that you need.

const gameCode = (function () {

  const a = 1;

  function consolelog() {
    console.log(`success${a}`);
  }

  return {
    consolelog: consolelog
  }

});

export default gameCode;

In your other file:

import gameCode from './gameCode';

componentDidMount() {
  const gc = gameCode();
  gc.consolelog(); // success1
}

DEMO

Upvotes: 1

Sagiv b.g
Sagiv b.g

Reputation: 31024

First of all, you don;t need to call it with the this key word once you imported it. You just call it that way: gameCode();.
Second, you are not returning anything from this function, hence you can't access it's nested function.
I think you need to re think the way you expose objects and functions.
For example, GameCode.js can look like this:

 const consolelog = function (a){
    console.log("success!");
    console.log(a);
 }
 export consolelog;

And then import it in your component:

import {consolelog} from '../utility/gamecode';

Edit
As a followup to your comment, if you need a function that will nest other functions and variables then you can create a class;

class GameCode {
  constructor(){
    this.consolelog = this.consolelog.bind(this);
  }

  consolelog(a){
      console.log("success!");
      console.log(a);
  }
}
export default GameCode;  

Then import it in you Component:

import GameCode from '../utility/gamecode'; // notice the import for default exports

Upvotes: 0

Dekel
Dekel

Reputation: 62536

Your Game class doesn't have a gameCode method so you can't use this.gameCode inside any of it's methods.

If you imported the gameCode inside the js file, you can use it anywhere inside:

componentDidMount(){
    gameCode();
};

The problem here is that the function gameCode in your example doesn't do anything - it only define a new function (locally) every time you call it. It's not an object that you can use to call it's function...

If gameCode was an object, you could have use:

gameCode.consolelog(something);

but it's not

You can change the gameCode to something like that:

export default gameCode = {
    consolelog: function (a){
        console.log("success!");
        console.log(a);
    }
}

And now since gameCode is an object, with the consolelog attribute as a function, you can use gameCode.consolelog(...) inside your Game class.

Upvotes: 2

Related Questions