[ReactJS] Uncaught TypeError: this.state is not a function

Default
,

Bonjour,

Je suis entrain de suivre le tuto sur RactJS, je suis au chap5: les évènements. J'essaye de mettre en place un nombre qui s'incrémente au fil du temps et un bouton qui permet de faire pause cette incrémentation.

Ce que je fais

class IncrementWithPause extends React.Component {

    constructor(props){
        super(props)
        this.state = {n: 0, timer: null}
    }

    componentDidMount() {
        this.play()
    }

    componentWillUnmount() {
        this.pause()
    }

    increment(){
        this.setState(function(state, props){
            return{n: state.n + 1}
        })
    }

    pause(){
        clearInterval(this.state.timer)
        this.setState({
            timer: null
        })
    }

    play(){
        this.state({
            timer: setInterval(this.increment.bind(this), 1000)
        })
    }

    render() {
        return <div> 
            Valeur: {this.state.n}
            <button onClick={this.pause.bind(this)}> Pause </button>
         </div>
    }

}

function Home() {
    return <div>
        <IncrementWithPause />
    </div>
}

ReactDOM.render(<Home/>, document.querySelector('#app'))

Ce que j'obtiens

Uncaught TypeError: this.state is not a function
play http://127.0.0.1:5500/index.html line 24 > scriptElement:92
componentDidMount http://127.0.0.1:5500/index.html line 24 > scriptElement:67
React 17
http://127.0.0.1:5500/index.html line 24 > scriptElement:125
standalone 6/babel.min.js:24
standalone 6/babel.min.js:24
standalone 6/babel.min.js:24
standalone 6/babel.min.js:24
index.html line 24 > scriptElement:92:18
The above error occurred in the component:
in IncrementWithPause (created by Home)
in div (created by Home)
in Home

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries. react-dom.development.js:19662:15
Uncaught TypeError: this.state is not a function
play http://127.0.0.1:5500/index.html line 24 > scriptElement:92
componentDidMount http://127.0.0.1:5500/index.html line 24 > scriptElement:67
React 17
http://127.0.0.1:5500/index.html line 24 > scriptElement:125
standalone 6/babel.min.js:24
standalone 6/babel.min.js:24
standalone 6/babel.min.js:24
standalone 6/babel.min.js:24
index.html line 24 > scriptElement:92:18
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in IncrementWithPause (created by Home)
in div (created by Home)
in Home react-dom.development.js:82:32

3 Réponse

Default
,

c'est normale, steState ne prend pas de function en parametre. c'est plus un truc du genre qu'il faut ecrire this.setState({n:this.state.n + 1})

44803
,

Bonjour,

Je pense que le problème vient du fait que le contexte this de tes fonctions appelées depuis la métode "render()" ne renvoie pas vers la classe directement. Il faudrait dans ton constructeur que tu bind the this de cette manière:

constructor(props){
        super(props)
        this.state = {n: 0, timer: null}

        this.increment = this.increment.bind(this)
        this.pause = this.pause.bind(this)
        // pour toutes tes fonctions ...
    }
Default
,

Bon le sujet ne semble plus actif, mais au cas où l'auteur revienne..
Dans ta méthode play, tu a écris this.state(...) au lieu de this.setState(...).

Corrige ça et ça devrait être OK (si pas d'autres erreurs)

@Defy, pour info this.setState peut prendre une fonction en param :

https://fr.reactjs.org/docs/faq-state.html#what-is-the-difference-between-passing-an-object-or-a-function-in-setstate

C'est même très utile pour être sûr de la valeur du state