一般来说,React和JS对我来说都是新的,所以我在这方面还是有点差。在这种情况下,我最不了解的是React Hooks以及它们有时不更新的问题。我知道为什么以及如何避免多次调用setter之类的东西,但这个特别的问题对我来说很难理解,甚至很难正确地使用google。我要么在这里找到基于类的this.state内容,要么在这里找到未回答的问题。
如何在我需要的时候更新钩子。例如,这是Material-UI中的Autocomplete组件。当我在其中选择一个选项时,我希望将它的值放入getTables中的newFKSchema常量中以使用它。对于这个问题,只有这个方法的前三行是重要的。但console.log显示newFKSchema为空。如果我选择另一个选项,newFKSchema中将包含前一个选项。所以这就像是一圈的延迟。我不明白为什么会发生这种情况,以及如何让它像我想要的那样工作。对于混乱的代码,我很抱歉,我已经做了一些尝试让它工作。
如果这对你来说不难,请在提供解决方案后解释一下。
const allSchemas = [
'',
'ADDITIONAL',
'BOOKKEEPING',
'CB',
'DEPOSIT',
'DOGORG',
'GENERALUSE',
'NSI',
'PAYMENTS',
'PLASTIC',
'SAFECELL',
'SWIFT',
'TARIFF',
];
const [newFKSchema, setNewFKSchema] = React.useState(allSchemas[0]);
const getTables = (schema) => {
var newSchema = schema;
setNewFKSchema(newSchema);
console.log(newFKSchema);
if (newFKSchema !== '') {
superagent
.get('/api/tech')
.query({schema: schema})
.then((response) =>{
if (response.status === 200) {
const newTables = [];
response.body.forEach(e => {newTables.push(e)});
setAllTables(newTables);
}
})
.catch(error => {
if (error.response.statusCode === 400) {
alert("No tables were found!");
}
});
}
}
<FormControl fullWidth>
<Autocomplete
id="autocomplete-schema"
options={allSchemas.slice(1)}
value={newFKSchema}
onChange={(event, value) => {setNewFKSchemaError(false); getTables(value)}} //setNewFKSchema(value);
renderInput={(params) => <TextField {...params} label="Schema name" variant="outlined" fullWidth />} />
<FormHelperText className={classes.formHelper}>
{newFKSchemaError ? "Needs input!" : ''}
</FormHelperText>
</FormControl> 发布于 2020-05-24 20:44:27
好的,让我们来看看这里发生了什么:
您可以使用参数event和value在onChange触发器中调用getTables(value)。
value设置为newFKSchema,您将其定义为allSchemas[0],即''
然后执行以下操作:
const getTables = (schema) => {
var newSchema = schema;
setNewFKSchema(newSchema);
console.log(newFKSchema);我们知道该模式是''。因此,newSchema也将为'',并且setNewFKSchema也会将架构设置为'',显然控制台日志也将记录''
那么,你到底期望发生什么呢?
发布于 2020-05-24 20:47:52
React state updates are asynchronous,您将在setNewFKSchema之后不久执行一个console.log,因此您将看到之前的值。
修复
const getTables = (schema) => {
var newSchema = schema;
setNewFKSchema(newSchema);
console.log(newFKSchema); //<------ don't do this
console.log(newSchema);//<------ do this
if (newFKSchema !== '') {
...您可以对代码进行的一个改进是简单地在onChange上执行setnewFKSSchema,并使用带有newFKSSchema的useEffect作为依赖项。这基本上就是调用你的api并在你做select的时候做一些事情。
像这样的
...
useEffect(() => {
// var newSchema = schema;
//setNewFKSchema(newSchema);
console.log(newFKSchema); //<---- this will always print latest value
if (newFKSchema !== '') {
superagent
.get('/api/tech')
.query({schema: schema})
.then((response) =>{
if (response.status === 200) {
const newTables = [];
response.body.forEach(e => {newTables.push(e)});
setAllTables(newTables);
}
})
.catch(error => {
if (error.response.statusCode === 400) {
alert("No tables were found!");
}
});
}
}, [newFKSSchema])Autocomplete
<Autocomplete
id="autocomplete-schema"
options={allSchemas.slice(1)}
value={newFKSchema}
onChange={(event, value) => {setNewFKSchemaError(false); setNewFKSchema(value)}}
renderInput={(params) => <TextField {...params} label="Schema name" variant="outlined" fullWidth />} />发布于 2020-05-24 21:18:34
我会使用带有newFKSchema的useEffect中的place getTables作为依赖项
示例
const allSchemas = [
'',
'ADDITIONAL',
'BOOKKEEPING',
'CB',
'DEPOSIT',
'DOGORG',
'GENERALUSE',
'NSI',
'PAYMENTS',
'PLASTIC',
'SAFECELL',
'SWIFT',
'TARIFF',
];
const { FormControl, FormHelperText, TextField } = window.MaterialUI;
const { Autocomplete } = window.MaterialUILab;
const { useState, useEffect } = React;
const renderInput = (params) => <TextField {...params} label="Schema name" variant="outlined" fullWidth />
const getTables = (schema) => Promise.resolve([1,2,3])
const App = () => {
const [{error, schemas, schema}, setData] = useState({
error: false,
schemas: [],
schema: null,
});
const [tables, setTables] = useState([]);
useEffect(() => {
setData(data => ({
...data,
schemas: allSchemas
}))
}, []);
useEffect(() => {
console.log(schema);
if(!schema) {
return () => {};
}
getTables(schema).then(result => {
setTables(schema);
})
}, [schema]);
const onChange = (event, schema) => {
setData(data => ({
...data,
schema,
error: schema ? false : true
}))
}
return <FormControl fullWidth>
<Autocomplete
id="autocomplete-schema"
options={schemas}
value={schema}
onChange={onChange}
renderInput={renderInput} />
<FormHelperText>
{error ? "Needs input!" : ''}
</FormHelperText>
</FormControl>
}
ReactDOM.render(
<App />,
document.getElementById('root')
);<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script src="https://unpkg.com/@material-ui/core@latest/umd/material-ui.development.js"></script>
<div id="root"></div>
<script src="https://unpkg.com/material-ui-lab-umd@4.0.0-alpha.32/material-ui-lab.development.js"></script>
<div id="root"></div>
https://stackoverflow.com/questions/61986042
复制相似问题