反应挂钩在获取选项后未设置 select 值
react hooks not setting the select value after fetching options
- 我正在使用 api 调用组件安装来获取测试套件列表。 Api returns 按时间顺序列出。
- 将它们设置为 select 下拉菜单的选项 (Material-UI)。
- 然后将 selected 选项设置为最新的 testSuite 并使用其 Id 获取相应的 testSuite 数据。
- 数据检索成功,正在显示饼图。
- Api 调用工作正常,React 开发工具显示要设置的 selectedTestSuite 值 correctly.But DOM 不显示 select select 下拉列表中的离子。
有人可以告诉我这段代码中的错误是什么吗?提前致谢。
import clsx from 'clsx';
import PropTypes from 'prop-types';
import { Doughnut } from 'react-chartjs-2';
import { makeStyles } from '@material-ui/styles';
import axios from 'axios';
import { useSpring, animated } from 'react-spring';
import '../../Dashboard.css';
import MenuItem from '@material-ui/core/MenuItem';
import {
Card,
CardHeader,
CardContent,
Divider,
TextField,
} from '@material-ui/core';
import CircularProgress from '@material-ui/core/CircularProgress';
const useStyles = makeStyles(() => ({
circularloader: {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
},
actions: {
justifyContent: 'flex-end',
},
inputField: {
width: '150px',
},
}));
const TestSuiteVsScanCount = (props) => {
const { className, ...rest } = props;
const classes = useStyles();
const [doughData, setDoughData] = useState([]);
const [dataLoadedFlag, setDataLoadedFlag] = useState(false);
const [testSuites, setTestSuites] = useState([]);
const [selectedTestSuite, setSelectedTestSuite] = useState({});
useEffect(() => {
function getTestSuites() {
axios.get('http://localhost:3000/api/v1/testsuite/12').then((resp) => {
setTestSuites(resp.data.reverse());
});
}
getTestSuites();
}, []);
useEffect(() => {
if (testSuites.length > 0) {
setSelectedTestSuite(() => {
return {
type: testSuites[0].TestSuiteName,
id: testSuites[0].TestSuiteId,
};
});
}
}, [testSuites]);
useEffect(() => {
function getTestSuiteData() {
let doughData = [];
if (selectedTestSuite.id) {
axios
.get(
'http://localhost:3000/api/v1/summary/piechart/12?days=30&testsuiteid=' +
selectedTestSuite.id,
)
.then((resp) => {
resp.data.forEach((test) => {
doughData = [test.TestCount, test.ScanCount];
});
setDoughData({
labels: ['Test Count', 'Scan Count'],
datasets: [
{
data: doughData,
backgroundColor: ['#FF6384', '#36A2EB'],
hoverBackgroundColor: ['#FF6384', '#36A2EB'],
},
],
});
setDataLoadedFlag(true);
});
}
}
getTestSuiteData();
}, [selectedTestSuite]);
const ChangeType = (id) => {
testSuites.forEach((suite) => {
if (suite.TestSuiteId === id) {
setSelectedTestSuite({
type: suite.TestSuiteName,
id: suite.TestSuiteId,
});
}
});
};
return (
<Card {...rest} className={clsx(classes.root, className)}>
<CardHeader
action={
<TextField
select
label="Select Test Suite"
placeholder="Select Tests"
value={selectedTestSuite.id}
className={classes.inputField}
name="tests"
onChange={(event) => ChangeType(event.target.value)}
variant="outlined"
InputLabelProps={{
shrink: true,
}}
>
{testSuites.map((testSuite) => (
<MenuItem
key={testSuite.TestSuiteId}
value={testSuite.TestSuiteId}
>
{testSuite.TestSuiteName}
</MenuItem>
))}
</TextField>
}
title="Test Suite vs Scan Count"
/>
<Divider />
<CardContent>
<div>
{dataLoadedFlag ? (
<Doughnut data={doughData} />
) : (
<CircularProgress
thickness="1.0"
size={100}
className={classes.circularloader}
/>
)}
</div>
</CardContent>
<Divider />
</Card>
);
};
TestSuiteVsScanCount.propTypes = {
className: PropTypes.string,
};
export default TestSuiteVsScanCount;
我在同事的帮助下解决了这个问题,方法是将 selectedTestSuite
的初始状态设置为 {type:'', id:0}
而不是 {}
。
改变了这个
const [selectedTestSuite, setSelectedTestSuite] = useState({});
对此
const [selectedTestSuite, setSelectedTestSuite] = useState({type:'', id:0});
但我不确定为什么会这样。
我认为主要问题是当您使用 undefined
将 value
传递给 TextField
组件时,TextField
组件将假定它是不受控制的组件。
当您将 selectedTestSuite
的初始状态设置为 {}
时,selectedTestSuite.id
的 value
将是未定义的。您可以在 https://material-ui.com/api/text-field/
中找到 value
API 参考资料
- 我正在使用 api 调用组件安装来获取测试套件列表。 Api returns 按时间顺序列出。
- 将它们设置为 select 下拉菜单的选项 (Material-UI)。
- 然后将 selected 选项设置为最新的 testSuite 并使用其 Id 获取相应的 testSuite 数据。
- 数据检索成功,正在显示饼图。
- Api 调用工作正常,React 开发工具显示要设置的 selectedTestSuite 值 correctly.But DOM 不显示 select select 下拉列表中的离子。
有人可以告诉我这段代码中的错误是什么吗?提前致谢。
import clsx from 'clsx';
import PropTypes from 'prop-types';
import { Doughnut } from 'react-chartjs-2';
import { makeStyles } from '@material-ui/styles';
import axios from 'axios';
import { useSpring, animated } from 'react-spring';
import '../../Dashboard.css';
import MenuItem from '@material-ui/core/MenuItem';
import {
Card,
CardHeader,
CardContent,
Divider,
TextField,
} from '@material-ui/core';
import CircularProgress from '@material-ui/core/CircularProgress';
const useStyles = makeStyles(() => ({
circularloader: {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
},
actions: {
justifyContent: 'flex-end',
},
inputField: {
width: '150px',
},
}));
const TestSuiteVsScanCount = (props) => {
const { className, ...rest } = props;
const classes = useStyles();
const [doughData, setDoughData] = useState([]);
const [dataLoadedFlag, setDataLoadedFlag] = useState(false);
const [testSuites, setTestSuites] = useState([]);
const [selectedTestSuite, setSelectedTestSuite] = useState({});
useEffect(() => {
function getTestSuites() {
axios.get('http://localhost:3000/api/v1/testsuite/12').then((resp) => {
setTestSuites(resp.data.reverse());
});
}
getTestSuites();
}, []);
useEffect(() => {
if (testSuites.length > 0) {
setSelectedTestSuite(() => {
return {
type: testSuites[0].TestSuiteName,
id: testSuites[0].TestSuiteId,
};
});
}
}, [testSuites]);
useEffect(() => {
function getTestSuiteData() {
let doughData = [];
if (selectedTestSuite.id) {
axios
.get(
'http://localhost:3000/api/v1/summary/piechart/12?days=30&testsuiteid=' +
selectedTestSuite.id,
)
.then((resp) => {
resp.data.forEach((test) => {
doughData = [test.TestCount, test.ScanCount];
});
setDoughData({
labels: ['Test Count', 'Scan Count'],
datasets: [
{
data: doughData,
backgroundColor: ['#FF6384', '#36A2EB'],
hoverBackgroundColor: ['#FF6384', '#36A2EB'],
},
],
});
setDataLoadedFlag(true);
});
}
}
getTestSuiteData();
}, [selectedTestSuite]);
const ChangeType = (id) => {
testSuites.forEach((suite) => {
if (suite.TestSuiteId === id) {
setSelectedTestSuite({
type: suite.TestSuiteName,
id: suite.TestSuiteId,
});
}
});
};
return (
<Card {...rest} className={clsx(classes.root, className)}>
<CardHeader
action={
<TextField
select
label="Select Test Suite"
placeholder="Select Tests"
value={selectedTestSuite.id}
className={classes.inputField}
name="tests"
onChange={(event) => ChangeType(event.target.value)}
variant="outlined"
InputLabelProps={{
shrink: true,
}}
>
{testSuites.map((testSuite) => (
<MenuItem
key={testSuite.TestSuiteId}
value={testSuite.TestSuiteId}
>
{testSuite.TestSuiteName}
</MenuItem>
))}
</TextField>
}
title="Test Suite vs Scan Count"
/>
<Divider />
<CardContent>
<div>
{dataLoadedFlag ? (
<Doughnut data={doughData} />
) : (
<CircularProgress
thickness="1.0"
size={100}
className={classes.circularloader}
/>
)}
</div>
</CardContent>
<Divider />
</Card>
);
};
TestSuiteVsScanCount.propTypes = {
className: PropTypes.string,
};
export default TestSuiteVsScanCount;
我在同事的帮助下解决了这个问题,方法是将 selectedTestSuite
的初始状态设置为 {type:'', id:0}
而不是 {}
。
改变了这个
const [selectedTestSuite, setSelectedTestSuite] = useState({});
对此
const [selectedTestSuite, setSelectedTestSuite] = useState({type:'', id:0});
但我不确定为什么会这样。
我认为主要问题是当您使用 undefined
将 value
传递给 TextField
组件时,TextField
组件将假定它是不受控制的组件。
当您将 selectedTestSuite
的初始状态设置为 {}
时,selectedTestSuite.id
的 value
将是未定义的。您可以在 https://material-ui.com/api/text-field/
value
API 参考资料