【问题标题】:Render a container based on logic React/Redux基于逻辑 React/Redux 渲染容器
【发布时间】:2018-08-22 11:52:19
【问题描述】:

我的 App.js 中有两个容器,状态保存在 Redux 存储中。

 <StartGameContainer/>
 <GameContainer/>

我的应用程序的状态有一个名为 "gameStatus" 的属性,该属性设置为 false。如果为真,我正在尝试使用此属性在GameContainer 中呈现我的组件。当我单击 StartGameContainer 中的“开始”按钮时,此属性设置为 true。

当 App 最初呈现时,它会注意到此属性为 false。当我单击开始按钮时,它对呈现来自GameContainer 的内容没有任何影响。我怎样才能做到这一点或弄错了这个布局?

编辑

GameContainer.js

const mapStateToProps = state => (
    {
        board: state.boardGame.board,
        gameStatus: state.boardGame.gameStatus
    }
);

const mapDispatchToProps = dispatch => {
    return {
        initGame: () => {
            dispatch(allActions.initGame())
        },

        selectCol : (val) => {
            dispatch(allActions.dropTile(val))
        }
    }
};

const GameContainer = connect(mapStateToProps, mapDispatchToProps)(GridCells);

class GridCells extends Component {

    componentDidMount() {
        this.props.initGame();
    }

    render() {
        if(this.props.gameStatus){
            return (
                <div className="game">
                    <table>
                        <thead>
                        </thead>
                        <tbody>
                        {this.props.board.map((row, i) => (
                            <RowCells key={i} row={row} select={this.props.selectCol}/>
                        ))}
                        </tbody>
                    </table>
                </div>
            )
        }else{
            return(<div></div>)
        }
    }
}

StartGameContainer.js

const mapDispatchToProps = dispatch => {
    return{
        pickPlayer: (currPlayer) => {
            dispatch(allActions.setPlayer(currPlayer))
        }
    }
};
const StartGameContainer = connect(null, mapDispatchToProps)(StartGame);


class StartGame extends Component{
    constructor(props){
        super(props);
        this.players = ['myself', 'service'];
        this.selectedVal = 1;
    }

    selectedPlayer(event){
        this.selectedVal = event.target.value === 'myself' ? 1 : 2;
    }

    render(){
        let options = this.players.map((val) => {
            return (<option key={val} value={val}>{val}</option>)
        });
        return(
            <div className='startGame'>
                <select name="players" id="players" onChange={this.selectedPlayer.bind(this)}>
                    {options}
                </select>
                <button onClick= {() => {this.props.pickPlayer(this.selectedVal)}}>Start Game</button>
            </div>
        )
    }
}

【问题讨论】:

  • 请附上GameContainer的代码
  • @ChrisCousins 在原始问题中编辑
  • 具体问题是什么?您目前对问题的技术描述基本上是“它不起作用”。是商店更新了,但连接的组件没有重新渲染?或者该操作已调度,但商店没有得到更新?有很多地方可能会发生此问题,必须缩小范围。

标签: javascript reactjs redux


【解决方案1】:

不完全确定您的 Redux 逻辑是什么样的......但您的问题源于对 hoisting 工作原理的误解。

尝试将两个连接代码行放在类定义下方:

class StartGame extends Component{ ... }

const StartGameContainer = connect(null, mapDispatchToProps)(StartGame)

查看SO answer 了解 JS 类是如何被提升但未初始化的。

“在定义之前使用类绝不是一个好主意”

这是一个简化的示例,可帮助您更好地理解为什么您的代码没有引发错误,但也无法正常工作。考虑一下这个 sn-p:

function logYourClass() {
  console.log(yourClass)
  var yourClass = 'all the class details'
}
logYourClass()

如果你运行它,你会注意到undefined 被记录,并且没有“yourClass is not defined”ReferenceError 被抛出。这是因为上面的代码相当于写:

function logYourClass() {
  var yourClass
  console.log(yourClass)
  yourClass = 'all the class details'
}
logYourClass()

另外值得注意的是 ES6 letconst 声明没有提升。尝试将上述代码中的 var 替换为其中任一关键字,您将看到 Uncaught ReferenceError。

function logYourClass() {
  console.log(yourClass)
  const yourClass = 'all the class details'
}
logYourClass()

【讨论】:

  • @RRP 这是否解决了您的问题?不要在没有反馈的情况下悄悄溜走
猜你喜欢
  • 2021-08-16
  • 2018-05-30
  • 2016-03-26
  • 2016-02-22
  • 1970-01-01
  • 2021-02-21
  • 1970-01-01
  • 2017-01-05
  • 2021-03-16
相关资源
最近更新 更多