如何从另一个类访问ReactJS中的render内的变量(编辑:另一个js页面)(正在使用ES6和Node)

时间:2016-10-30 03:28:47

标签: javascript reactjs ecmascript-6

我希望在游戏的AI移动(startThinking功能)时禁用onClick,这样玩家就不会随意点击游戏的任何部分并搞砸了。

这是我的类的代码,我想从中访问变量onclick和cursor(由** **包围的相关位):

class Grid extends React.Component{
        constructor(props){
          super(props);
          var pos = props.pos;
          this.xPos = 2+(pos%9)*66+"px";
          this.yPos = 2+(Math.floor(pos/9))*66+"px";
          this.borderTop = "none";
          this.borderLeft = "none";
          this.borderRight = "none";
          this.borderBottom = "none";
          if(pos%3==0){
            this.borderLeft = "solid";
          }
          if(pos%9==8){
            this.borderRight = "solid";
          }
          if(pos>71){
            this.borderBottom = "solid";
          }
          if((pos%27)<9){
            this.borderTop = "solid";
          }
      }

        render(){
          var pos = this.props.pos;
          var icon = this.props.icon;
          var backgroundColor = (icon==="none")?((!this.props.legal)?((pos%2)?"white":"#f2f2f2"):((pos%2)?"rgb(177, 251, 169)":"rgb(157, 228, 150)")):((icon==="x")?"rgb(243, 125, 125)":"#6f83f3");
          var choice = "";
          var **onclick** = (this.props.legal)?this.props.onclick:(()=>{});
          var **cursor** = (this.props.legal)?"pointer":"default";
          if(icon !== "none"){
              choice = (<div className='icon'>{icon}</div>);
          }
          return(<div onClick={onclick} style={{cursor:cursor,backgroundColor:backgroundColor,top:this.yPos,left:this.xPos,borderLeft:this.borderLeft,borderRight:this.borderRight,borderTop:this.borderTop,borderBottom:this.borderBottom}} className='grid' >{choice}</div>);
        }
      }

这是我要从中访问变量onclick和cursor的类,并在gameAI开始思考之前将它们更改为默认值(即未激活),然后我想在gameAI结束后将它们恢复为原始状态思考并采取了行动。相关位包围** **

class Board extends React.Component {
        constructor(props){
          super(props);
          this.state = {
            model: curGame
          }
          setSimBoard(this);
        }

        render() {
          var model = this.state.model;
          var i = -1;

          var comps = model.grid.map((sq)=>{
            i++;
            var n = "block_"+i;
            var leg = model.legals.indexOf(i)>-1;
            return <Grid id={n} key={n} pos={i} icon={sq.icon} legal={leg} onclick={
              ((i)=>{
                  **  return ()=>{
     // the comments are what i tried, didn't work    Grid.onclick = (()=>{});
                    //  Grid.cursor = "default";
                      startThinking(i);
                      model.makeMove(i);
                   //   Grid.onclick = (this.props.legal)?this.props.onclick:(()=>{});
                    //  Grid.cursor = (this.props.legal)?"pointer":"default";
                      this.setState({model:model});

                    }
                  })(i) **
            }/>;
          });

          return (
            <div>
              <div>{comps}</div>
              <BoardStatus model={model}/>
              <WinCover model={model}/>
            </div>
          );
        }
      }

最后,这里是startThinking函数,它位于另一个js文件中。评论是我试过的。 ai属于另一个文件,它是gameAI,而它正在进行计算以进行移动。

function startThinking(i){
  //document.getElementById('id').style.pointerEvents = 'none'; 
  console.log("thinking..");
  ai.postMessage({game:Object.assign({"ai":true}, curGame) ,move:i});
//  document.getElementById('id').style.pointerEvents = 'auto';  
}

我真的很感激这方面的帮助!非常感谢你!

编辑:所以,Pranesh Ravi告诉我如何从另一个类的类中访问变量。但是,由于这并没有解决我的问题,我想知道如何从另一个文件ai.js访问onclick和游标变量,其相关部分如下所示,以及超级相关部分被** **包围。注释是我试图在gameAI工作时禁用click的,这给了我一个参考错误,说明没有定义Board是有意义的。

    var thinkTime = 2000;
    var think = false;
    var maxDepth = 6;
    onmessage = function(msg){
   ** //  Board.onclick = (()=>{});
    //  Board.cursor = "default"  **
      var game = msg.data.game;
      var playerMove = msg.data.move;
      think = true;
      var search = new SearchTree(game,playerMove,0);
      var bestMove = search.traverse(maxDepth,true);
      console.log(bestMove);
      postMessage(bestMove.move);
  **   // Board.onclick = (this.props.legal)?this.props.onclick:(()=>{});
     // Board.cursor = (this.props.legal)?"pointer":"default";  **
}

2 个答案:

答案 0 :(得分:1)

像Redux这样的库解决了这个问题。

您有一个中央存储库,其中包含游戏状态的信息。我给你两种解决方法。

选项1.获取Grid组件的ref并调用一个返回所需信息的函数。

选项2.由于获取组件的引用是不好的做法,因此更纯粹的方法是在呈现时将函数传递给子组件。用于注册获取所需信息的函数。这是我推荐的方法。

class Board extends Component {

  constructor(props) {
    super(props);
    this.registerStateFetcher = this.registerStateFetcher.bind(this);
  }

  registerStateFetcher(fetcher) {
    this.stateFetcher = fetcher;
  }

  render() {
    return <Grid registerStateFetcher={ this.registerStateFetcher } />
  }
}

class Grid extends Component {

  constructor(props) {
    super(props);
    props.registerStateFetcher(this.getGameState.bind(this));
  }

  getGameState() {
    // recollect info needed and return
    return {};
  }

}

答案 1 :(得分:0)

在您的项目中,Board可以从Grid而不是React.Component延伸。并在super的{​​{1}}内拨打constructorBoard将运行其父类的super。因此,constructor内的所有this现在都可以在Grid中使用。添加了一个简单的例子来证明这一点。

希望这有帮助!

&#13;
&#13;
Board
&#13;
class Grid extends React.Component{
  constructor(props){
    super(props)
    this.onClick = 'This is a onclick variable'
    this.cursor = 'This is cursor'
  }
  render(){
    return <h1>Render from Component Grid</h1>
  }
}

class Board extends Grid{ //extending Grid
  constructor(props){
    super(props) //calling super to run the constructor of Grid
  }
  
  render(){
    console.log(this.onClick) //Accessing onClick from Grid
    console.log(this.cursor) //Accessing cursor from Grid
    return <h1>Render from Component Board</h1>
  }
}

ReactDOM.render(
  <div>
    <Grid/>
    <Board/>
  </div>
  , document.getElementById('app')
)
&#13;
&#13;
&#13;