0

I am new on React.js and I don't understand, how I should pass the score children to app parent, and reset all components score via "Reset Components Score" on the app parent button, I try everything noting work, thanks for the help!

Player children components:

import React, { useState } from 'react';

function Player(props) {
const [score, setScore] = useState(0);

function scoreUp(params) {
setScore(score + 1);
}

function scoreDown(params) {
score <= 0 ? setScore(0) : setScore(score - 1);
}

const scoreReset = () => {
setScore(0);
};
return (
 <div>
   <center>
    <h1>{props.name}</h1>
    <h2>{score}</h2>
    <button style={{ backgroundColor: 'green' }} onClick={scoreUp}>
      +
    </button>
    <button style={{ backgroundColor: 'red' }} onClick={scoreDown}>
      -
    </button>
    <button style={{ backgroundColor: 'purple' }} onClick={scoreReset}>
      Reset {props.name} Score
    </button>
   </center>
 </div>
 );
}

 export default Player;

App Parent:

import React from 'react';
import Player from './Player';

function App() {
return (
  <div>
  <Player name='Benjamin' />
  <Player name='Alex' />
  <button style={{ backgroundColor: 'black' }}>
    Reset Components Score
  </button>
  </div>
  );
  }

 export default App;

the App img

Benja
  • 3
  • 2
  • Welcome, Benja. Before posting, search for questions addressing the same issue. This question has been asked many times, for example: https://stackoverflow.com/questions/40722382/how-to-pass-state-back-to-parent-in-react. That said, this is the main use case for a centralized Redux state store. I recommend reading up on that. It greatly simplifies state management between child/parent components – ChiefMcFrank Jan 29 '22 at 19:25

1 Answers1

1

Benja. In react, data flows only in one direction (from parent to child). In this case, we want to lift the state one level up ( the parent component: App) so that both the parents and children have access to the state. so we will take the score state from the player component to the app component. then we will pass the score and a handler function as well as props to the player component.

with that our code will look like this =>

the App component:

import React, { useState } from "react";
import Player from "./components/Player";

interface PlayerProps {
  [key: string]: number;
}

function App() {
  const [playerScore, resetPlayerScore] = useState<PlayerProps>({
    Benjamin: 0,
    Alex: 0,
  });
  const handle_playerScore = (player: string) => {
    const scoreUp = () => {
      resetPlayerScore({ ...playerScore, [player]: playerScore[player] + 1 });
    };

    const scoreDown = () => {
      resetPlayerScore({ ...playerScore, [player]: playerScore[player] - 1 });
    };

    const scoreReset = () => {
      resetPlayerScore({ ...playerScore, [player]: 0 });
    };

    return { scoreUp, scoreDown, scoreReset };
  };

  const resetAll = () => {
    resetPlayerScore({ Benjamin: 0, Alex: 0 });
  };

  return (
    <div>
      <Player
        score={playerScore.Benjamin}
        name="Benjamin"
        handleScore={handle_playerScore}
      />
      <Player
        score={playerScore.Alex}
        name="Alex"
        handleScore={handle_playerScore}
      />

      <button onClick={resetAll}>Reset All</button>
    </div>
  );
}

export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

and our Player component:

import React from "react";

interface PlayerProps {
  name: string;
  score: number;
  handleScore: (player: string) => {
    scoreUp: () => void;
    scoreDown: () => void;
    scoreReset: () => void;
  };
}

const Player = ({ name, score, handleScore }: PlayerProps) => {
  const { scoreUp, scoreDown, scoreReset } = handleScore(name);
  return (
    <div>
      <h1>{name}</h1>
      <h2>{score}</h2>
      <button style={{ backgroundColor: "green" }} onClick={scoreUp}>
        +
      </button>
      <button style={{ backgroundColor: "red" }} onClick={scoreDown}>
        -
      </button>
      <button style={{ backgroundColor: "purple" }} onClick={scoreReset}>
        Reset {name} Score
      </button>
    </div>
  );
};

export default Player;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

We can apply other techniques as well to solve this scenario. such as Higher-order components and render props. They also have the same underlying principle.