javascript - 在 168 个对象的状态数组中使用 Map 时,React 卡住 1~2 秒

标签 javascript reactjs react-hooks

当我在执行 axios.put 后尝试更新对象状态数组的属性时,就会出现问题。

这是我的代码:

状态 - useEffect

//...
const [volunteers, setVolunteers] = useState([]);
//...
useEffect(() => {
    async function loadVolunteers() {
      api
        .get('volunteers')
        .then(response => {
          const data = response.data.map(volunteer => ({
            ...volunteer,
            notChecked: volunteer.confirmed === null,
            confirmedText: volunteer.confirmed ? 'Deferido' : 'Indeferido',
            createdDateFormatted: format(
              parseISO(volunteer.createdAt),
              "d 'de' MMMM'/'yyyy",
              {
                locale: pt,
              }
            ),
          }));
          setVolunteers(data);
        })
        .then(() => {
          api
            .get('departments')
            .then(response => {
              setDepartments(response.data);
              setLoading(false);
            })
            .catch(() => {
              toast.error(
                'Ops! Aconteceu algum problema ao buscar as Inscrições. Tente novamente mais tarde e/ou contate o Programador'
              );
            });
        })
        .catch(() => {
          toast.error(
            'Ops! Aconteceu algum problema ao buscar as Inscrições. Tente novamente mais tarde e/ou contate o Programador'
          );
        });
    }

    if (!isAdmin) {
      history.push('/dashboard');
    }

    loadVolunteers();
    dispatch(changePage('inscricoes'));
  }, []); // eslint-disable-line
//...
  const updateDepartment = async (id, department_id) => {
    try {
      await api.put(`volunteers/${id}/department`, {
        department_id,
      });
      setVolunteers(
        volunteers.map(volunteer => {
          if (volunteer.id === id) {
            volunteer.department_id = department_id;
            return volunteer;
          }
          return volunteer;
        })
      );
      toast.success('Departamento atualizado');
    } catch (err) {
      toast.error('Erro ao atualizar departamento');
    }
  };

如果我删除 setVolunteers 指令,此方法会立即运行。

但是当我尝试在志愿者数组/状态中执行该映射时,应用程序卡住了 1~2 秒。

为什么?

在其余的 react 代码下面迭代志愿者数组。

{volunteers.map((volunteer, index) => (
  <Card
    key={volunteer.id}
    className={classes.card}
    variant="outlined"
  >
    <CardContent>
      <TextField
        variant="outlined"
        margin="none"
        required
        select
        fullWidth
        id="gender"
        value={volunteer.department_id}
        placeholder="Selecione"
        onChange={e =>
          updateDepartment(volunteer.id, e.target.value)
        }
        label="Selecione seu sexo"
        name="gender"
      >
        {departments.map(option => (
          <MenuItem key={option.id} value={option.id}>
            {option.name}
          </MenuItem>
        ))}
      </TextField>
      <Typography variant="h5" component="h2">
        {volunteer.user.name}
      </Typography>
      <Typography className={classes.pos} color="textSecondary">
        {volunteer.user.phone}
      </Typography>
      <Typography variant="body2" component="p">
        <strong>Líder: </strong>
        {volunteer.user.leader_name}
      </Typography>
    </CardContent>
    <CardActions className={classes.subActions}>
      {volunteer.notChecked ? (
        <>
          <Button
            size="small"
            fullWidth
            variant="contained"
            color="primary"
            disabled={loadConfirm}
            onClick={() =>
              handleConfirmation(index, volunteer.id, true)
            }
          >
            Deferido
          </Button>
          <Button
            size="small"
            fullWidth
            variant="contained"
            disabled={loadConfirm}
            onClick={() =>
              handleConfirmation(index, volunteer.id, false)
            }
          >
            Indeferido
          </Button>
        </>
      ) : (
        <Button
          size="small"
          fullWidth
          variant="contained"
          color="primary"
          disabled
        >
          {volunteer.confirmed ? 'Deferido' : 'Indeferido'}
        </Button>
      )}
      <Button
        size="small"
        fullWidth
        variant="contained"
        className={classes.deny}
        disabled={loadConfirm}
        onClick={() => handleDelete(index, volunteer.id, true)}
      >
        Excluir
      </Button>
    </CardActions>
  </Card>
))}

最佳答案

您可以使用回调函数来更新状态。

试试这个。

const updateDepartment = async (id, department_id) => {
  try {
    await api.put(`volunteers/${id}/department`, {
      department_id
    });
    setVolunteers(prevState => {
      let Volunteers = prevState.map(volunteer => {
        if (volunteer.id === id) {
          volunteer.department_id = department_id;
          return volunteer;
        }
        return volunteer;
      });
      return Volunteers;
    });
    toast.success("Departamento atualizado");
  } catch (err) {
    toast.error("Erro ao atualizar departamento");
  }
};

关于javascript - 在 168 个对象的状态数组中使用 Map 时,React 卡住 1~2 秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60038260/

相关文章:

javascript - 从字符串元素数组创建 DOM 元素,然后将结果加入 render()

javascript - 在 React Hooks 中切换 bool 状态

reactjs - react useState setter导致重新渲染

javascript - 使用 struts2 提交表单时调用 Javascript 函数

javascript - 将项目数据传递给 react 模态

javascript - 如何继承EventTarget对象?

javascript - 使用 ReactJS 在井字游戏应用程序中撤消按钮

javascript - 为什么 useMemo 不起作用?我用错了吗?

javascript - Ember.js - 组件中模型的更改不会保存

javascript - 我想以月格式绘制 x 轴..通过此代码,我可以逐年绘制