运行函数以更新组件构造函数(及更高版本)的状态

时间:2018-03-02 13:49:42

标签: reactjs

我试图写一个小型的战斗卡片游戏作为学习练习来理解React,特别是状态。在游戏中我喜欢每一个都可以播放一张新的牌,所以我创建了一个绘制牌并从构造函数中调用它的函数:

class App extends Component {
    constructor() {
        super();
        this.state = {
            hero: {
                str: 2,
                currentStr: 2,
                def: 2,
                currentDef: 2,
                health: 100,
                currentHealth: 74,
                moves: 3,
                currentMoves: 3,
                cards: [1, 1, 1, 2, 2, 2],
                draw: 4,
                hand: [],
            },
        };

        this.drawHand = this.drawHand.bind(this);
        this.drawHand();
    }

    drawHand() {
        let draw = [];
        let cards = this.state.hero.cards.slice();
        for (let i = 0; i < this.state.hero.draw; i++) {
            const min = 0;
            const max = cards.length -1;
            const position = Math.floor(Math.random() * (max - min + 1)) + min;
            const item = cards.splice(position, 1);
            draw.push(item[0]);
        }

        draw = draw.sort();

        let hero = {...this.state.hero};
        hero.hand = draw;

        this.setState({
            hero: hero
        });
    }

    render() {
        return (
            <div className="row">
                {this.state.hero.hand.join(',')}
            </div>
        );
    };
};

但是,当我创建App组件时,我收到错误

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op.

我已尝试阅读已安装/未安装的组件,但我似乎无法弄清楚这里发生了什么。我想我需要在安装App时在渲染过程中稍后调用drawHand方法 - 是否有我可以使用的事件或类似事件?

1 个答案:

答案 0 :(得分:3)

在将组件安装到DOM中之前运行

构造函数

所以你想要的是在componentDidMount生命周期方法中执行该方法。

像这样

class App extends Component {
    constructor() {
        super();
        this.state = {
            hero: {
                str: 2,
                currentStr: 2,
                def: 2,
                currentDef: 2,
                health: 100,
                currentHealth: 74,
                moves: 3,
                currentMoves: 3,
                cards: [1, 1, 1, 2, 2, 2],
                draw: 4,
                hand: [],
            },
        };

        this.drawHand = this.drawHand.bind(this);
    }

    drawHand() {
        let draw = [];
        let cards = this.state.hero.cards.slice();
        for (let i = 0; i < this.state.hero.draw; i++) {
            const min = 0;
            const max = cards.length -1;
            const position = Math.floor(Math.random() * (max - min + 1)) + min;
            const item = cards.splice(position, 1);
            draw.push(item[0]);
        }

        draw = draw.sort();

        let hero = {...this.state.hero};
        hero.hand = draw;

        this.setState({
            hero: hero
        });
    }

    componentDidMount() {
       this.drawHand();
    }

    render() {
        return (
            <div className="row">
                {this.state.hero.hand.join(',')}
            </div>
        );
    };
};