在反应中推入数组 object 但不在屏幕上呈现
Pushing into an array object in react but not rendering on the screen
我正在使用 React 并通过标签数组 object 显示一些标签。现在,我想动态地执行此操作。因此,如果用户单击按钮,object 会更新,用户界面也应相应更新。这里的问题是我在单击按钮后更新了数组,正如我在 onclick 处理程序中编写的控制台日志行所证明的那样。但用户界面不会相应更新。只有数组显示值。这是初始数组的样子:
const labelsArray = [
{ label: 'Hey There', sublabel1: 'How are you?' },
{
label: 'Greetings', sublabel1: 'Fellows'
},
{ label: 'Awesome', sublabel1: 'Youre doing great', sublabel2: 'cool' }
];
我想将 warningLabel 和 errorLabel 附加到此数组的第二个 object。因此,由于数组是 0 索引的,所以我在 onclick 处理程序中执行了以下操作:
const appendLabel = async () => {
labelsArray[1].warningLabel = "Hello";
labelsArray[1].errorLabel = "Hello";
console.log(labelsArray)
};
数组更新,但用户界面未更新。这真的很奇怪。
此外,这与反应状态突变无关,我知道这一点是因为我在试图弄清楚时对这个主题进行了研究。所以要明确一点,这与状态突变无关,这可能有人将其作为重复问题提出。它更像是一个 react/object 结构问题。但我可能是错的!无论如何,任何帮助表示赞赏。谢谢!
这是我的整个组件供参考
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);
您需要在状态中设置 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);
};
我正在使用 React 并通过标签数组 object 显示一些标签。现在,我想动态地执行此操作。因此,如果用户单击按钮,object 会更新,用户界面也应相应更新。这里的问题是我在单击按钮后更新了数组,正如我在 onclick 处理程序中编写的控制台日志行所证明的那样。但用户界面不会相应更新。只有数组显示值。这是初始数组的样子:
const labelsArray = [
{ label: 'Hey There', sublabel1: 'How are you?' },
{
label: 'Greetings', sublabel1: 'Fellows'
},
{ label: 'Awesome', sublabel1: 'Youre doing great', sublabel2: 'cool' }
];
我想将 warningLabel 和 errorLabel 附加到此数组的第二个 object。因此,由于数组是 0 索引的,所以我在 onclick 处理程序中执行了以下操作:
const appendLabel = async () => {
labelsArray[1].warningLabel = "Hello";
labelsArray[1].errorLabel = "Hello";
console.log(labelsArray)
};
数组更新,但用户界面未更新。这真的很奇怪。
此外,这与反应状态突变无关,我知道这一点是因为我在试图弄清楚时对这个主题进行了研究。所以要明确一点,这与状态突变无关,这可能有人将其作为重复问题提出。它更像是一个 react/object 结构问题。但我可能是错的!无论如何,任何帮助表示赞赏。谢谢!
这是我的整个组件供参考
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);
您需要在状态中设置 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);
};