首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React Hook未更新

React Hook未更新
EN

Stack Overflow用户
提问于 2020-05-24 20:34:33
回答 3查看 230关注 0票数 2

一般来说,React和JS对我来说都是新的,所以我在这方面还是有点差。在这种情况下,我最不了解的是React Hooks以及它们有时不更新的问题。我知道为什么以及如何避免多次调用setter之类的东西,但这个特别的问题对我来说很难理解,甚至很难正确地使用google。我要么在这里找到基于类的this.state内容,要么在这里找到未回答的问题。

如何在我需要的时候更新钩子。例如,这是Material-UI中的Autocomplete组件。当我在其中选择一个选项时,我希望将它的值放入getTables中的newFKSchema常量中以使用它。对于这个问题,只有这个方法的前三行是重要的。但console.log显示newFKSchema为空。如果我选择另一个选项,newFKSchema中将包含前一个选项。所以这就像是一圈的延迟。我不明白为什么会发生这种情况,以及如何让它像我想要的那样工作。对于混乱的代码,我很抱歉,我已经做了一些尝试让它工作。

如果这对你来说不难,请在提供解决方案后解释一下。

代码语言:javascript
复制
  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>  
EN

回答 3

Stack Overflow用户

发布于 2020-05-24 20:44:27

好的,让我们来看看这里发生了什么:

您可以使用参数eventvalueonChange触发器中调用getTables(value)

value设置为newFKSchema,您将其定义为allSchemas[0],即''

然后执行以下操作:

代码语言:javascript
复制
const getTables = (schema) => {
    var newSchema = schema;
    setNewFKSchema(newSchema);
    console.log(newFKSchema);

我们知道该模式是''。因此,newSchema也将为'',并且setNewFKSchema也会将架构设置为'',显然控制台日志也将记录''

那么,你到底期望发生什么呢?

票数 1
EN

Stack Overflow用户

发布于 2020-05-24 20:47:52

React state updates are asynchronous,您将在setNewFKSchema之后不久执行一个console.log,因此您将看到之前的值。

修复

代码语言:javascript
复制
const getTables = (schema) => {
    var newSchema = schema;
    setNewFKSchema(newSchema);
    console.log(newFKSchema); //<------ don't do this
    console.log(newSchema);//<------ do this

    if (newFKSchema !== '') {
  ...

您可以对代码进行的一个改进是简单地在onChange上执行setnewFKSSchema,并使用带有newFKSSchemauseEffect作为依赖项。这基本上就是调用你的api并在你做select的时候做一些事情。

像这样的

代码语言:javascript
复制
...
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

代码语言:javascript
复制
<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 />} />
票数 1
EN

Stack Overflow用户

发布于 2020-05-24 21:18:34

我会使用带有newFKSchemauseEffect中的place getTables作为依赖项

示例

代码语言:javascript
复制
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')
  );
代码语言:javascript
复制
<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>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61986042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档