React - 通过 props 在 child 中设置状态

React - setState in child through props

我对 React 比较陌生,我正在尝试为 child 组件(SportTile)设置 object 的状态 onclick 事件。我很乐意通过使用单独的 useState() 挂钩来更新单个变量的状态,但是,当您有很多变量时,这是一项繁琐的任务。所以我使用了一个名为 object 的 isClicked ,它为各种运动存储了一个布尔值,表明它们是否被用户选择。

我正在寻找的功能是,每当单击 SportTile 时,其 isClicked["sportname"] 值设置为 true 并且其余设置为假。一次只能有一项运动是真实的。 在控制台记录 isClicked object 中的 onclick() 函数时,我得到了所需的值,但它们没有在Parent 组件的(预订h1 标签

import React from 'react';
import SportTile from '../SportTile';
import './booking.css';
import { useState } from 'react';
import SportsSoccerRoundedIcon from '@mui/icons-material/SportsSoccerRounded';
import SportsBasketballRoundedIcon from '@mui/icons-material/SportsBasketballRounded';
import SportsVolleyballIcon from '@mui/icons-material/SportsVolleyball';
import SportsTennisIcon from '@mui/icons-material/SportsTennis';

const Booking = () => {
  const [isClicked, setIsClicked] = useState({
    Football: false,
    Basketball: false,
    Volleyball: false,
    Tennis: false,
  });

  return (
    <div className='booking'>
      <div className='booking__body'>
        <div className='booking__left'>
          <h1>SELECT SPORT</h1>
          <SportTile
            sportname={'Football'}
            icon={<SportsSoccerRoundedIcon />}
            clicked={setIsClicked}
            isClicked={isClicked}
            // test={setTestclicked}
            // istestClicked={istestClicked}
          />
          <SportTile
            sportname={'Basketball'}
            icon={<SportsBasketballRoundedIcon />}
            clicked={setIsClicked}
            isClicked={isClicked}
          />
          <SportTile
            sportname={'Volleyball'}
            icon={<SportsVolleyballIcon />}
            clicked={setIsClicked}
            isClicked={isClicked}
          />
          <SportTile
            sportname={'Tennis'}
            icon={<SportsTennisIcon />}
            clicked={setIsClicked}
            isClicked={isClicked}
          />

          <h1>Football : {isClicked.Football.toString()} </h1>
          <h1>Basketball : {isClicked.Basketball.toString()} </h1>
          <h1>Volleyball : {isClicked.Volleyball.toString()} </h1>
          <h1>Tennis : {isClicked.Tennis.toString()} </h1>
        </div>
        <div className='booking__right'>Right Side</div>
      </div>
    </div>
  );
};

export default Booking;

import { Button } from '@mui/material';
import React from 'react';
import './sportTile.css';

const SportTile = ({
  sportname,
  icon,
  clicked,
  isClicked,     
}) => {
  function onclick() {        
    Object.keys(isClicked).map((key) => {
      if (key == sportname) {
        isClicked[key] = true;
      } else {
        isClicked[key] = false;
      }
    });      
    clicked(isClicked);
    console.log(isClicked);
  }

  return (
    <Button className='sportname__button' onClick={onclick}>
      <div className='sportname__buttonColumn'>
        {icon}
        {sportname}
      </div>
    </Button>
  );
};

export default SportTile;

也许我遗漏了明显的东西,但如果有人能指出正确的方向,我将不胜感激

您永远不应该传递原始的 setState 方法。 在 Booking 组件中创建一个新方法:

const setIsClickedWrapper = (sportKey) = {
   setIsClicked((isClicked) => Object.keys(isClicked).map((key) => sportKey === key)
} 

并在 SportTile 组件中调用:

const onclick = () => { setIsClickedWrapper(sportname) }     

但我认为如果 isClicked 只是当前点击的运动键的字符串就足够了:

const setIsClickedWrapper = (sportKey) = {
   setIsClicked(sportKey)
}