1

I'm starting in ReactJS and I'm doing a score system for my game in React.

I used a component called Score to manage it.

I did a score value in the state that can be incremented by increment().

The problem is that I would like to use this function from my App component (it's an example, I created incrementScore() to show it).

However my increment() can't gain access to this.setState() when the function is called from another component.

Note that I created a button "Increment" inside Score.js which uses increment() and it's works perfectly.

Have you a solution or could you just give a clue? Thanks!

App.js:

import Score from './Score'

class App extends React.Component {

  incrementScore() {
    Score.prototype.increment()
  }

  render() {
    return (
        <div>
          <h1 id="title">Game</h1>
          <Score />
          <Canvas /> {/*Not important here, just for the game*/}
        </div>
    )
  }
}

export default App

Score.js:

import React from 'react'

class Score extends React.Component {

  constructor() {
    super()
    this.state = {
      score: 0
    }
    this.increment = this.increment.bind(this)
  }

  increment() {
    this.setState({
      score: this.state.score + 1 //this.state.score + 1
    })
  }

  render() {
    return (
      <div>
        <p id="score">Score: {this.state.score}</p>
        <button>Incrementer</button>
      </div>
    )
  }
}

export default
4
  • 2
    If you need to have the state in the parent component, then define the increment method there, and pass it down to the child component as a prop. There is good example of this in the official React docs: reactjs.org/docs/lifting-state-up.html Commented Dec 22, 2018 at 15:21
  • Thanks for your answer but if my other component isn't parent of score ? If I want to access incrementScore() by an other js class ? Commented Dec 22, 2018 at 16:00
  • Usually all your components are descendants of a common "root" component, which is often called App, as here. So given any 2 components you can always find a common ancestor (usually below the level of App itself) which you can lift the state to. Commented Dec 22, 2018 at 16:12
  • Ok... so we never can mix components and non-components classes ? Even when we want to create objects which represents canvas drawings ? Commented Dec 22, 2018 at 16:44

1 Answer 1

2

As mentioned by Robin, just move your state to your parent App component, and let your Score component be a 'stateless' component. Also, make sure to pass the increment function down as a prop and use that within your button as an onClick function.

class App extends React.Component {
constructor() {
    super()
    this.state = {
      score: 0
    }
    this.increment = this.increment.bind(this)
  }

  increment() {
    this.setState({
      score: this.state.score + 1 //this.state.score + 1
    })
  }

  render() {
    return (
      <div>
        <h1 id="title">Game</h1>
        <Score scoreCount={this.state.score} increment={this.increment}/>
      </div>
    )
  }
}
const Score = props =>
      <div>
        <p id="score">Score: {props.scoreCount}</p>
        <button onClick={props.increment}>Incrementer</button>
      </div>

See a live example here: https://codesandbox.io/s/wq4kqqz0mw

Sign up to request clarification or add additional context in comments.

1 Comment

how to achieve kind of same in react hooks? "suppose a functional component(FC) which call a function to set-state which is outside the FC scope"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.