【问题标题】:Pushing into an array object in react but not rendering on the screen在反应中推入数组对象但不在屏幕上呈现
【发布时间】:2021-12-18 00:33:10
【问题描述】:

我正在使用 react 并通过标签的数组对象显示一些标签。现在,我想动态地做到这一点。因此,如果用户单击按钮,则对象会更新,用户界面也应相应更新。这里的问题是我在单击按钮后更新了数组,正如我在 onclick 处理程序中编写的控制台日志行所证明的那样。但用户界面不会相应更新。只有数组显示值。这是初始数组的样子:

const labelsArray = [
  { label: 'Hey There', sublabel1: 'How are you?' },
  {
    label: 'Greetings', sublabel1: 'Fellows'
  },
  { label: 'Awesome', sublabel1: 'Youre doing great', sublabel2: 'cool' }
];

我想在这个数组的第二个对象上附加一个warningLabel 和errorLabel。因此,由于数组索引为 0,因此我在 onclick 处理程序中执行了以下操作:

const appendLabel = async () => {
  labelsArray[1].warningLabel = "Hello";
  labelsArray[1].errorLabel = "Hello";
  console.log(labelsArray)
};

数组更新,但不更新用户界面。这真的很奇怪。

另外,这与反应状态突变无关,我知道这是因为我在试图弄清楚时对这个主题进行了研究。所以为了清楚起见,它不是关于状态突变,这可能会让有人把它作为一个重复的问题。它更多的是一个反应/对象结构问题。但我可能是错的!无论如何,任何帮助表示赞赏。谢谢!

这是我的整个组件供参考

import React, { useState } from 'react';
import { Button, Typography } from '@material-ui/core';
import { withStyles } from '@material-ui/core/styles/';
import Stepper from '@material-ui/core/Stepper';
import Step from '@material-ui/core/Step';
import StepLabel from '@material-ui/core/StepLabel';
import StepConnector from '@material-ui/core/StepConnector';
import PropTypes from 'prop-types';


const styles = theme => ({
  stepLabelRoot: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center'
  },
  checklistHeader: {
    fontWeight: 'bold',
    marginTop: '80px'
  },
  connectorIcon: {
    color: theme.palette.text.secondary
  },
  stepper: {
    background: 'none',
    fontWeight: 'bold'
  },
  checkListImageContainer: {
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center'
  },
  connector: {

  },
  activeConnector: {
    border: 'solid 1px #6fef71'
  },
  stepIcon: {
    height: '35px',
    width: '35px',
    '&:hover': {
      backgroundColor: 'rgba(134, 141, 150, 0.37)',
      borderRadius: '50%'
    },
  },
  activeStepIcon: {
    backgroundColor: 'yellow'
  },
  label: {
    fontWeight: 'bold',
    display: 'flex',
    fontSize: '15px'
  },
  sublabel: {
    fontWeight: 'normal',
    fontSize: '13px'
  },
  errorLabel: {
    color: 'red'
  },
  warningLabel: {
    color: 'yellow'
  },
  step: {
    '&$completed': {
      color: 'lightgreen'
    },
    '&$active': {
      color: 'pink'
    },
    '&$disabled': {
      color: 'red'
    },
  },
  alternativeLabel: {},
  active: {

  }, // needed so that the &$active tag works
  completed: {

  },
  disabled: {

  },
  labelContainer: {
    '&$alternativeLabel': {
      marginTop: 0
    },
  },
});

const labelsArray = [
  { label: 'Random text?', sublabel1: 'Lorem Ipsum' },
  {
    label: 'Another random text', sublabel1: 'Hello World'
  },
  { label: 'Cool', sublabel1: 'cool', sublabel2: 'ayo' }
];


const Checklist = ({ classes,activeStep }) => {

  return (
    <React.Fragment>
      <Stepper alternativeLabel activeStep={2} connector={<StepConnector />} className={classes.stepper}>
        {labelsArray.map(label => (
          <Step key={label} completed>
            <StepLabel active
              completed
              StepIconProps={{
                classes: {
                  root: classes.step,
                  completed: classes.completed,
                  active: classes.active,
                  disabled: classes.disabled
                }
              }}>
              <div className={classes.stepLabelRoot}>
                <span className={classes.label}>
                  {label.label}
                </span>
                <span className={classes.sublabel}>
                  {label.sublabel1}
                </span>
                <span className={classes.sublabel}>
                  {label.sublabel2}
                </span>
                <span className={classes.sublabel}>
                  {label.sublabel3}
                </span>
                <span className={classes.errorLabel}>
                  {label.errorLabel && <img src="/static/images/lock-material.png" alt="img" style={{ height: '15px', width: '15px' }} />}
                  {label.errorLabel}
                </span>
                <span className={classes.warningLabel}>
                  {label.warningLabel && <img src="/static/images/warning-sign.png" alt="img" style={{ height: '15px', width: '15px' }} />}
                  {label.warningLabel}
                </span>
              </div>
            </StepLabel>
          </Step>
        ))}
      </Stepper>
      <Button onClick={() => appendLabel()}>Hello</Button>
    </React.Fragment>
  );
};

Checklist.defaultProps = {
  activeStep: -1
};

Checklist.propTypes = {
  classes: PropTypes.object.isRequired,
  form: PropTypes.bool.isRequired,
  activeStep: PropTypes.number
};

export default withStyles(styles, { withTheme: true })(Checklist);

【问题讨论】:

  • 显示您的组件。您必须将此数组保持在组件状态并通过 setState 对其进行变异
  • 您好,感谢您的评论。我更新了帖子以显示我的组件代码。 @罗伯特

标签: javascript arrays reactjs object oop


【解决方案1】:

您需要将labelsArray设置为状态并进行相应更新,以便在用户单击按钮时重新渲染组件

编辑: 对状态执行此操作的一种方法是:

const LABELS =[
  { label: 'Hey There', sublabel1: 'How are you?' },
  { label: 'Greetings', sublabel1: 'Fellows' },
  { label: 'Awesome', sublabel1: 'Youre doing great', sublabel2: 'cool' }
];

const [labelsArray, setLabelsArray] = useState(LABELS);

const appendLabel = () => {
  let editedLabels = [...labelsArray];
  editedLabels[1].warningLabel = "Hello";
  editedLabels[1].errorLabel = "Hello";
  setLabelsArray(editedLabels);
};

【讨论】:

  • 您的响应是有道理的,但我在实现这样一个对象数组时遇到了麻烦,它与 .push 方法具有相同的效果。因为如果不是 errorLabel 则会显示 warningLabel ,反之亦然。你能给我一个指导吗? @迭戈
  • 我编辑了答案
  • 感谢您的帮助,但它仍然与我没有使用状态时一样。这是更新控制台中的阵列但不更新用户界面。 @迭戈法拉利
  • 我再次编辑更改了在 appendLabel 中分配editedLabels 的行
  • 谢谢!成功了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-22
  • 2019-11-03
  • 2018-10-30
相关资源
最近更新 更多