只需在Reaction中更新列表中一个元素的状态 [英] Just update the state of one element on the list in React

查看:28
本文介绍了只需在Reaction中更新列表中一个元素的状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是反应新手,我有一个问题。我有一个情态词列表,在情态词关闭后,我会在屏幕上显示写在该情态词上的结果。我的问题是,当我在一种模式下书写时,列表上的所有项目与图像上的结果相同。

我的代码沙箱在这里:https://codesandbox.io/s/react-modal-631f5?file=/src/ModalTest.tsx:0-2792

export default () => {
  const [open, setOpen] = React.useState(false);
  const [createAbleInputs, setCreateAbleInputs] = React.useState([]);
  const [selectedValues, setSelectedValues] = React.useState([]);
  const [country] = React.useState([
    { value: "1", label: "a" },
    { value: "2", label: "b" },
    { value: "3", label: "c" }
  ]);
  console.log({ createAbleInputs, selectedValues });
  function handleClickOpen() {
    setOpen(true);
  }

  function handleClose() {
    setOpen(false);
  }

  const a = [{ name: "a" }, { name: "b" }];
  const classes = useStyles();
  const combinedArray =
    createAbleInputs === null
      ? [...selectedValues]
      : [...selectedValues, ...createAbleInputs];
  return (
    <Fragment>
      {a.map((name) => (
        <div>
          <Button onClick={handleClickOpen}>ModalButton</Button>
          <div>
            Selected options on the modal were:{" "}
            {combinedArray?.length
              ? combinedArray.map((item, idx) =>
                  idx !== 0 ? `, ${item.label}` : item.label
                )
              : ""}
          </div>
        </div>
      ))}

      <Dialog
        maxWidth={"sm"}
        fullWidth={true}
        open={open}
        onClose={handleClose}
        aria-labelledby="alert-dialog-title"
        aria-describedby="alert-dialog-description"
        classes={{
          paperFullWidth: classes.paperFullWidth
        }}
      >
        <DialogTitle id="alert-dialog-title">Dialog</DialogTitle>
        <DialogContent
          classes={{
            root: classes.dialogContentRoot
          }}
        >
          <Grid container spacing={2}>
            <Grid item xs={6}>
              <FormControl style={{ width: "100%" }}>
                <ReactSelect
                  handleSelectValues={setSelectedValues}
                  isMulti={true}
                  options={country}
                />
              </FormControl>
            </Grid>
          </Grid>
          <Grid container spacing={2}>
            <CreatableInputOnly handleSelectValues={setCreateAbleInputs} />
          </Grid>
        </DialogContent>
        <DialogActions>
          <Button onClick={handleClose} variant="contained">
            Close
          </Button>
        </DialogActions>
      </Dialog>
    </Fragment>
  );
};

推荐答案

不确定这是否是您想要的,但我会这么做sandbox

import React, { Fragment } from "react";
import {
  Grid,
  Dialog,
  Button,
  FormControl,
  DialogActions,
  DialogContent,
  DialogTitle
} from "@material-ui/core/";

import ReactSelect from "./reactMaterialSelect";
import { makeStyles } from "@material-ui/core/styles";
import CreatableInputOnly from "./CreatableInputOnly";

const useStyles = makeStyles({
  paperFullWidth: {
    overflowY: "visible"
  },
  dialogContentRoot: {
    overflowY: "visible"
  }
});

export default () => {
  const [country] = React.useState([
    { value: "1", label: "a" },
    { value: "2", label: "b" },
    { value: "3", label: "c" }
  ]);

  const [a, setA] = React.useState([
    {
      name: "a",
      selectedValues: [],
      createAbleInputs: [],
      combinedArray: [],
      open: false
    },
    {
      name: "b",
      selectedValues: [],
      createAbleInputs: [],
      combinedArray: [],
      open: false
    }
  ]);

  function handleClickOpen(index) {
    let aTemp = Object.assign([], a);
    aTemp[index].open = true;
    setA(aTemp);
  }

  function handleClose(index) {
    let aTemp = Object.assign([], a);
    aTemp[index].open = false;
    setA(aTemp);
  }

  function setSelectedValues(value, index) {
    console.log("setSelectedValues", value, index);
    let aTemp = Object.assign([], a);
    aTemp[index].selectedValues = value;
    aTemp[index].combinedArray = [
      ...aTemp[index].selectedValues,
      ...aTemp[index].createAbleInputs
    ];
    setA(aTemp);
  }

  function setCreateAbleInputs(value, index) {
    let aTemp = Object.assign([], a);
    aTemp[index].createAbleInputs = value;
    aTemp[index].combinedArray = [
      ...aTemp[index].selectedValues,
      ...aTemp[index].createAbleInputs
    ];
    setA(aTemp);
  }

  return (
    <Fragment>
      {a.map((obj, index) => (
        <div key={index}>
          <Button
            onClick={(e) => {
              handleClickOpen(index);
            }}
          >
            Modal Button {obj.name}
          </Button>
          <div>
            Selected options on the modal were:{" "}
            {obj.combinedArray?.length
              ? obj.combinedArray.map((item, idx) =>
                  idx !== 0 ? `, ${item.label}` : item.label
                )
              : ""}
          </div>
          <Dialog
            maxWidth={"sm"}
            fullWidth={true}
            open={obj.open}
            onClose={(e) => {
              handleClose(index);
            }}
            aria-labelledby="alert-dialog-title"
            aria-describedby="alert-dialog-description"
            classes={{
              paperFullWidth: classes.paperFullWidth
            }}
          >
            <DialogTitle id="alert-dialog-title">Dialog</DialogTitle>
            <DialogContent
              classes={{
                root: classes.dialogContentRoot
              }}
            >
              <Grid container spacing={2}>
                <Grid item xs={6}>
                  <FormControl style={{ width: "100%" }}>
                    <ReactSelect
                      handleSelectValues={(value) => {
                        setSelectedValues(value, index);
                      }}
                      isMulti={true}
                      options={country}
                    />
                  </FormControl>
                </Grid>
              </Grid>
              <Grid container spacing={2}>
                <CreatableInputOnly
                  handleSelectValues={(value) => {
                    setCreateAbleInputs(value, index);
                  }}
                />
              </Grid>
            </DialogContent>
            <DialogActions>
              <Button
                onClick={(e) => {
                  handleClose(index);
                }}
                variant="contained"
              >
                Close
              </Button>
            </DialogActions>
          </Dialog>
        </div>
      ))}
    </Fragment>
  );
};

这篇关于只需在Reaction中更新列表中一个元素的状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆