Home > Blockchain >  React & Typescript - How to pass counter to parent
React & Typescript - How to pass counter to parent

Time:03-31

I am having trouble counting how many games are rated. So I managed to do, parent -> child : pass gameinfo data However, I am stuck for few days to figure out how to count how many games were rated.

Can someone please help me how I'm supposed to fix this part:

//in child : how to use props * callback function from parent at the same time ? 
export default function BoardCard(
  props: { game: Game; parentCallback: ICount },
  { parentCallback }: ICount
) //I am totally stuck on this part T0T 
...

or if there's any other efficient way on counting how many games were rated?

enter image description here

Below are my codes. I have added few comments explaining what i did:

Parent.tsx

import React, { useEffect, useState } from "react";
import BoardCardMain from "./component/BoardCardSurvey";
import { Button, Box, Grid, Container } from "@mui/material";
import WelcomeStepper from "../component/WelcomeStepper";
import { useNavigate } from "react-router-dom";
import { initSurvey } from "../../../api/user";
import { valueToPercent } from "@mui/base";

//Game Interface
export interface Game {
  gameNo: number;
  gameImg: string;
  gameName: string;
}

export default function Survey() {
  const [gameList, setGameList] = useState<Game[]>([]); //I get error if i remove <Game[]> type

  const [count, setCount] = useState(0);// to count how much games were rated

  useEffect(() => {
    setCount(0);
    setGameList(tempData.gameList); // connect API (temp Data for now)
     }, []);
//what am i supposed to do ;~;
  const countHandler = (cnt: number) => {
    if (cnt > 0) {
      setCount(count   1);
    }
  };

  return (
    <>
      <Grid
        container
        spacing={0}
        direction="column"
        alignItems="center"
        style={{ minHeight: "100%" }}
      >
        <Container style={{ marginTop: 20, padding: 10 }}>
          <Grid container spacing={2}>
            {gameList.map((game) => (
              <BoardCardMain
                key={game.gameNo}
                game={game}
                parentCallback={countHandler}
              ></BoardCardMain>
            ))}
          </Grid>
        </Container>
        <Button
          style={{ position: "fixed", bottom: "0px" }}
          type="submit"
          fullWidth
          variant="contained"
          color="primary"
          size="large"
        >
          Completed
        </Button>
      </Grid>
    </>
  );
}

// temp data before calling api
const tempData = {
  gameList: [
    {
      gameNo: 1,
      gameImg:
        "https://cf.geekdo-images.com/original/img/uqlrq_bQJqHpcaN7_7qocV5XfbU=/0x0/pic4718279.jpg",
      gameName: "Die Macher long title very long",
    },
    {
      gameNo: 12,
      gameImg:
        "https://cf.geekdo-images.com/original/img/o07K8ZVh0PkOpOnSZs1TuABb7I4=/0x0/pic4001505.jpg",
      gameName: "Dragonmaster",
    },
  ],
};

Child (BoardGameSurvey.tsx)

//import statements 


const initScore = 0;
interface ICount {
  parentCallback: (cnt: number) => void;
}

export default function BoardCard(
  props: { game: Game; parentCallback: ICount },
  { parentCallback }: ICount
) //I am totally stuck on this part T0T 
{
  const userno = useSelector((state: RootStateOrAny) => state.user.userNo);
  
  //I got how much score user rated if they rated
  const setStarRatings = (score: number) => {
   
    if (score > 0) {
      //if score is bigger than 0, it means its selected
      //alert(score);
      parentCallback(1); //pass One

    }
  };
  return (
    <Grid item xs={12} sm={4} md={3} lg={2.3}>
      <StyledCard variant="outlined">
        <CardActionArea>
          <ImgWrapper>
            <CardMedia
              sx={{
                position: "absolute",
                width: "100%",
                height: "100%",
                objectFit: "contain",
              }}
              component="img"
              image={props.game.gameImg}
              alt={props.game.gameName}
            />
          </ImgWrapper>
          <CardContent>
            <Grid container justifyContent="center">
              <GameTitle>{props.game.gameName}</GameTitle>
              <Box width="100%" />
              <StarRating
                initStarRate={0}
                gameNo={props.game.gameNo}
                userNo={userno}
                size={35}
                parentCallback={setStarRatings}
              />
            </Grid>
          </CardContent>
        </CardActionArea>
      </StyledCard>
    </Grid>
  );
}

CodePudding user response:

I think your problem is from here

export default function BoardCard(
  props: { game: Game; parentCallback: ICount },
  { parentCallback }: ICount
)

It should be

interface ICount {
  parentCallback: (cnt: number) => void;
  game: Game; //your game interface
}

export default function BoardCard(
  { game, parentCallback } : ICount
)
  • Related