Реагировать — использовать состояние для обновления значений или нет

#javascript #reactjs #use-state

#javascript #reactjs #использовать-состояние

Вопрос:

У меня есть форма с двумя столбцами. Левый столбец — это предлагаемое значение для правого столбца. В настоящее время я представляю оба значения из отдельных вызовов API. Это работает.

Это текущий код:

const dbContact = useDbContact(contact.Group); Это устанавливает значение текущих значений contact.Group из предложенных значений, передаваемых в вызов API.

Затем я позже использую это для вызова входного значения формы:

 <Form.Row> 
    <Form.Group as={Col} controlId="currentSecName" className="mb-2">
        <Form.Control type="input" name="1secname" value={contact.SecretaryName} readOnly />
    </Form.Group>
    <Form.Group as={Col} controlId="dbSecName" className="mb-2">
        <Form.Control type="input" name="2secname" value={dbContact.SecretaryName} readOnly />
    </Form.Group>

    <Button className="PrimaryButton" size="sm">
        Accept proposed
    </Button>
    <div class="divider" />
</Form.Row>
 

Теперь у меня все это работает, моим следующим шагом было заставить кнопку «принять» обновить текущее значение предложенным. Мой код выглядит примерно так:

 const dbContact = useDbContact(contact.Group);
const [dbSecName, setDbSecName] = useState(dbContact.SecretaryName)
 

и

<Form.Control type="input" name="2secname" value={dbSecName} readOnly />

что позволило бы мне изменить значение состояния ‘onClick’

Однако, когда я это делаю, я получаю ‘dbContact.SecretaryName не определено ‘. Теперь, я предполагаю, что, учитывая, что я запрашивал значение в форме напрямую, во время тестирования, мне повезло, что значение было заполнено до запроса, поэтому потенциально что-то не так с вызовом API.

Вот вызов API:

   async function getData(group) {
    try {
      const apiGroups = await API.graphql(graphqlOperation(queries.getNtig, { PK: "Group#"   group, SK: "Officers#2" }));

      let listItem = await apiGroups.data.getNTIG;
      let PK = await apiGroups.data.getNTIG.PK.split("#")[1];
      let secJson = await JSON.parse(apiGroups.data.getNTIG.Secretary);
      let id = 1;

      let receivedItems = {
        Id: id,
        PK: PK,
        SecretaryName: secJson.Name,
      };

      setList(receivedItems);
    } catch (err) {}
  }
  useEffect(() => {
    if (!isAuthenticated) {
      return;
    }
    getData(group);
  }, [isAuthenticated, group]);
  console.log(list);
  return list;
}
 

Я надеюсь, что кто-нибудь сможет мне помочь, это либо исправление логики, чтобы установка значения состояния работала, либо альтернатива изменению входного значения формы.

Ответ №1:

Я не уверен, что это правильный способ сделать это, но он работает, а также решает дополнительную проблему изменения неконтролируемого элемента при повторном отображении элемента, когда значение состояния изменяется при вызове API.

Здесь я получаю значения из вызова API и инициализирую setState:

  const dbContact = useDbContact(contact.Group);
 const [dbSecName, setDbSecName] = useState("");
 

Затем я использую useEffect с асинхронной функцией для ожидания значения из вызова API и setState с использованием этого значения:

 useEffect(() => {
    async function getDbContact() {
        let secName = await dbContact.SecretaryName;
        setDbSecName(secName);
        }
    getDbContact();
}, [dbContact.SecretaryName]);
 

Затем я могу использовать значение во вводе формы:

 <Form.Control type="input" name="2secname" value={dbSecName || ""} readOnly />
 

Очевидно, мне нужно обработать изменение состояния во вводе формы, но теперь это должно быть прямолинейно.

Я не разработчик, поэтому, если появится лучший ответ, я был бы рад его увидеть. На данный момент я, кажется, решил свою собственную проблему.