1. ホーム
  2. javascript

[解決済み] Reactで複数のMaterial UIチェックボックスを処理する

2022-03-05 13:17:30

質問

チェックボックスの値は、チェックボックスをオフにした場合は削除され、チェックした場合は追加されるようにしたいです。これまでのところ、私は配列に単一の値のみを与えるこのコードを持っていますが、私は1つの配列にすべてのチェックされた値を必要とします。

import React from 'react';
import DropDown from './DropDown';
import TextField from '@material-ui/core/TextField';
import TextareaAutosize from '@material-ui/core/TextareaAutosize';
import RadioButton from './RadioButtons';
import MultiSelect from './MultiSelect';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';
import FormControl from '@material-ui/core/FormControl';
import Grid from '@material-ui/core/Grid';
import Paper from '@material-ui/core/Paper';
import Button from '@material-ui/core/Button';
import Box from '@material-ui/core/Box';
import { DropzoneDialog } from 'material-ui-dropzone';
import createpagestyle from './Createpage.css';
import Chip from '@material-ui/core/Chip';
import AddCircleIcon from '@material-ui/icons/AddCircle';
import Checkbox from '@material-ui/core/Checkbox';
import { grey } from '@material-ui/core/colors';
import { useState } from 'react';

const useStyles = makeStyles((theme) => ({
  typography: {
    fontSize: '3.5 rem',
    fontWeight: '550',
    color: '#0E1941',

    [theme.breakpoints.down('md')]: {
      fontSize: '0.5rem',
    },
    [theme.breakpoints.up('md')]: {
      fontSize: '1.0rem',
    },
    [theme.breakpoints.up('lg')]: {
      fontSize: '1.2rem',
    },
  },

  Table: {
    width: '60%',
  },

  Td: {
    width: '250px',
  },
  Td_Checkbox: {
    width: '60px',
  },
}));

var Claim = [
  { key: 0, label: 'CLAIM OWNER', name: 'DESIREE MOHUKA' },
  { key: 1, label: 'AUTHORITY CONSULTANT', name: 'XXXXXXXXXXXX' },
  { key: 2, label: 'PROCESSOR CLAIM', name: 'XXXXXXXXXXXX' },
  { key: 3, label: 'CONTROLLLER', name: 'XXXXXXXXXXXX' },
  { key: 4, label: 'MANAGER', name: 'XXXXXXXXXXXX' },
];

var Dwelling = [
  { key: 0, label: 'CLAIM HANDLER', name: 'DESIREE MOHUKA' },
  { key: 1, label: 'CONTROLLLER', name: 'XXXXXXXXXXXX' },
  { key: 2, label: 'PERFORMER', name: 'XXXXXXXXXXXX' },
];

var Unscheduler_pp = [
  { key: 0, label: 'CLAIM HANDLER', name: 'DESIREE MOHUKA' },
  { key: 1, label: 'CONTROLLLER', name: 'XXXXXXXXXXXX' },
  { key: 2, label: 'PERFORMER', name: 'XXXXXXXXXXXX' },
];

export default function Participantpage(props) {
  if (props.visibility) {
    const classes = useStyles();
    const [participant, setParticipant] = React.useState([]);

    let handleCheckboxChange = (event) => {
      let newArray = [event.target.id];
      if (participant.includes(event.target.id)) {
        newArray = newArray.filter((value) => value !== event.target.id);
      }
      setParticipant(newArray);
    };

    return (
      <div>
        <Grid container spacing={2}>
          <Grid item xs={9}>
            POLICY: XXXXXXXXXX
          </Grid>
          <Grid item xs={3}>
            INSURED: XXXXXXXXXX
          </Grid>
          <Grid item xs={12}>
            <div style={{ backgroundColor: '#E9E9E9', width: '100%' }}>
              <Typography
                variant='body1'
                className={classes.typography}
                style={{
                  marginTop: '10px',
                  marginBottom: '30px',
                  font: 'normal normal medium 20px/24px Allstate Sans W',
                }}
              >
                CLAIM{' '}
              </Typography>
            </div>
          </Grid>
        </Grid>
        <tbody className={classes.Table}>
          {Claim.map((data) => {
            return (
              <tr>
                <td className={classes.Td_Checkbox}>
                  {' '}
                  <Checkbox
                    id={data.name}
                    onChange={handleCheckboxChange}
                    color='default'
                  />{' '}
                </td>
                <td className={classes.Td}>{data.label}</td>
                <td className={classes.Td}>{data.name}</td>
              </tr>
            );
          })}
        </tbody>

        <Grid container spacing={2}>
          <Grid item xs={12}>
            <div style={{ backgroundColor: '#E9E9E9', width: '100%' }}>
              <Typography
                variant='body1'
                className={classes.typography}
                style={{
                  marginTop: '10px',
                  marginBottom: '30px',
                  font: 'normal normal medium 20px/24px Allstate Sans W',
                }}
              >
                DWELLING{' '}
              </Typography>
            </div>
          </Grid>
        </Grid>
        <tbody className={classes.Table}>
          {Dwelling.map((data) => {
            return (
              <tr>
                <td className={classes.Td_Checkbox}>
                  {' '}
                  <Checkbox
                    id={data.name}
                    onChange={handleCheckboxChange}
                    color='default'
                  />{' '}
                </td>
                <td className={classes.Td}>{data.label}</td>
                <td className={classes.Td}>{data.name}</td>
              </tr>
            );
          })}
        </tbody>

        <Grid container spacing={2}>
          <Grid item xs={12}>
            <div style={{ backgroundColor: '#E9E9E9', width: '100%' }}>
              <Typography
                variant='body1'
                className={classes.typography}
                style={{
                  marginTop: '10px',
                  marginBottom: '30px',
                  font: 'normal normal medium 20px/24px Allstate Sans W',
                }}
              >
                UNSCHEDULER PERSONAL PROPERTY{' '}
              </Typography>
            </div>
          </Grid>
        </Grid>
        <tbody className={classes.Table}>
          {Unscheduler_pp.map((data) => {
            return (
              <tr>
                <td className={classes.Td_Checkbox}>
                  {' '}
                  <Checkbox
                    id={data.name}
                    onChange={handleCheckboxChange}
                    color='default'
                  />{' '}
                </td>
                <td className={classes.Td}>{data.label}</td>
                <td className={classes.Td}>{data.name}</td>
              </tr>
            );
          })}
        </tbody>
        {console.log(participant)}
      </div>
    );
  } else {
    return <div></div>;
  }
}

解決方法は?

上記のコードを再作成してみたところ、2つの解決策が見つかりました。つ目は ロジックをApp.jsで処理することは推奨されません。 .

しかし、App.jsで状態を作成し、別のコンポーネントでロジックを処理することで、2番目のオプションを使用することができます。

1つの状態を2つ以上の子コンポーネントで使用する必要がある場合は、reduxを使用することをお勧めします。

  1. 別コンポーネントで処理されるロジック
    App.js
import "./styles.css";
import Checkbox from "./Checkbox";

const CLAIMS = [
  { key: 0, label: "CLAIM OWNER", name: "DESIREE MOHUKA" },
  { key: 1, label: "AUTHORITY CONSULTANT", name: "XXXXXXXXXXXX" },
  { key: 2, label: "PROCESSOR CLAIM", name: "XXXXXXXXXXXX" },
  { key: 3, label: "CONTROLLLER", name: "XXXXXXXXXXXX" },
  { key: 4, label: "MANAGER", name: "XXXXXXXXXXXX" }
];

const DWELLINGS = [
  { key: 0, label: "CLAIM HANDLER", name: "DESIREE MOHUKA" },
  { key: 1, label: "CONTROLLLER", name: "XXXXXXXXXXXX" },
  { key: 2, label: "PERFORMER", name: "XXXXXXXXXXXX" }
];

const UNSCHEDULER_PP = [
  { key: 0, label: "CLAIM HANDLER", name: "DESIREE MOHUKA" },
  { key: 1, label: "CONTROLLLER", name: "XXXXXXXXXXXX" },
  { key: 2, label: "PERFORMER", name: "XXXXXXXXXXXX" }
];

export default function App() {
  return (
    <div>
      <div>
        <Checkbox list={CLAIMS} title="Claims" />
        <Checkbox list={DWELLINGS} title="Dwellings" />
        <Checkbox list={UNSCHEDULER_PP} title="Unscheduler" />
      </div>
    </div>
  );
}

チェックボックス.js

import { useState } from "react";

/* parses check box data from props.list element
 * @params {{title: string, list:{name: string, id: number}[]}} props
 */
const Checkbox = (props) => {
  const [participants, setParticipants] = useState([]);

  // logic to add or remove elements check or unchecked form an array.
  const handleCheckboxChange = (event) => {
    const id = event.target.id;
    setParticipants((currentParticipants) =>
      currentParticipants.includes(id)
        ? currentParticipants.filter((f) => f !== id)
        : [...currentParticipants, id]
    );
  };

  console.log("participants", participants);

  // creates all the checkbox based on the list array.
  const checkbox = props.list.map((m) => (
    <span key={m.key}>
      <input type="checkbox" id={m.key} onClick={handleCheckboxChange} />
      {m.name}
    </span>
  ));

  return (
    <div>
      <div>{checkbox}</div>
      <div>{props.title}</div>
    </div>
  );
};

export default Checkbox;


  1. App.jsで扱うロジック(必要な場合以外は推奨しない)
    App.js
import "./styles.css";
import Checkbox from "./Checkbox";
import { useState } from "react";

const CLAIMS = [
  { key: 0, label: "CLAIM OWNER", name: "DESIREE MOHUKA" },
  { key: 1, label: "AUTHORITY CONSULTANT", name: "XXXXXXXXXXXX" },
  { key: 2, label: "PROCESSOR CLAIM", name: "XXXXXXXXXXXX" },
  { key: 3, label: "CONTROLLLER", name: "XXXXXXXXXXXX" },
  { key: 4, label: "MANAGER", name: "XXXXXXXXXXXX" }
];

const DWELLINGS = [
  { key: 0, label: "CLAIM HANDLER", name: "DESIREE MOHUKA" },
  { key: 1, label: "CONTROLLLER", name: "XXXXXXXXXXXX" },
  { key: 2, label: "PERFORMER", name: "XXXXXXXXXXXX" }
];

const UNSCHEDULER_PP = [
  { key: 0, label: "CLAIM HANDLER", name: "DESIREE MOHUKA" },
  { key: 1, label: "CONTROLLLER", name: "XXXXXXXXXXXX" },
  { key: 2, label: "PERFORMER", name: "XXXXXXXXXXXX" }
];

export default function App() {
  const [claimParticipants, setClaimParticipants] = useState([]);
  const [dwellingParticipants, setDwellingParticipants] = useState([]);
  const [unschedulerParticipants, setUnschedulerParticipants] = useState([]);

  // logic to add or remove elements check or unchecked form an array.
  const handleCheckboxChange = (event, setParticipants) => {
    const id = event.target.id;
    setParticipants((currentParticipants) =>
      currentParticipants.includes(id)
        ? currentParticipants.filter((f) => f !== id)
        : [...currentParticipants, id]
    );
  };

  console.log("claimParticipants", claimParticipants);
  console.log("dwellingParticipants", dwellingParticipants);
  console.log("unschedulerParticipants", unschedulerParticipants);

  return (
    <div>
      <div>
        <Checkbox
          list={CLAIMS}
          title="Claims"
          handleCheckboxChange={(event) =>
            handleCheckboxChange(event, setClaimParticipants)
          }
        />
        <Checkbox
          list={DWELLINGS}
          title="Dwellings"
          handleCheckboxChange={(event) =>
            handleCheckboxChange(event, setDwellingParticipants)
          }
        />
        <Checkbox
          list={UNSCHEDULER_PP}
          title="Unscheduler"
          handleCheckboxChange={(event) =>
            handleCheckboxChange(event, setUnschedulerParticipants)
          }
        />
      </div>
    </div>
  );
}

チェックボックス.js

/* parses check box data from props.list element
 * @params {{title: string, handleCheckboxChange: Function, list:{name: string, id: number}[]}}
 */
const Checkbox = (props) => {
  // creates all the checkbox based on the list array.
  const checkbox = props.list.map((m) => (
    <span key={m.key}>
      <input type="checkbox" id={m.key} onClick={props.handleCheckboxChange} />
      {m.name}
    </span>
  ));

  return (
    <div>
      <div>{checkbox}</div>
      <div>{props.title}</div>
    </div>
  );
};

export default Checkbox;