简体   繁体   English

处理 Fluent UI React 中的 TextField 更改

[英]Handling TextField change in Fluent UI React

Using Fluent UI React, I'm displaying some data from an AppSync API in a TextField.使用 Fluent UI React,我在 TextField 中显示来自 AppSync API 的一些数据。 I want to be able to show text from the API for a contact form.我希望能够显示来自 API 的联系表单文本。 I then want to edit that text and click a button to post it back to the AppSync API.然后我想编辑该文本并单击一个按钮将其发送回 AppSync API。

If I use the TextField component on its own, I can then use a hook to set a variable to result of an AppSync API call and then have the TextField component read the value coming from the variable I set with the hook.如果我单独使用 TextField 组件,则可以使用挂钩将变量设置为 AppSync API 调用的结果,然后让 TextField 组件读取来自我使用挂钩设置的变量的值。 I can then edit that text as I feel like and its fine.然后我可以根据自己的感觉编辑该文本,并且很好。

The problem I have is that if I want to take edits to the TextField and set them using my hook I lose focus on the TextField.我遇到的问题是,如果我想对 TextField 进行编辑并使用我的钩子设置它们,我就会失去对 TextField 的关注。 To do this I am using the onChange property of TextField.为此,我使用了 TextField 的 onChange 属性。 I can set the variable fine but I have to keep clicking back in to the input window.我可以很好地设置变量,但我必须继续单击返回输入窗口。

Any thoughts on how I can keep the focus?关于如何保持专注的任何想法?

import React, { useEffect, useState } from 'react';
import { API, graphqlOperation } from 'aws-amplify';
import * as queries from '../../graphql/queries';
import { Fabric, TextField, Stack } from '@fluentui/react';

const PhoneEntryFromRouter = ({
  match: {
    params: { phoneBookId },
  },
}) => PhoneEntry(phoneBookId);

function PhoneEntry(phoneBookId) {
  const [item, setItem] = useState({});

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await API.graphql(
          graphqlOperation(queries.getPhoneBookEntry, { id: phoneBookId })
        );
        setItem(response.data.getPhoneBookEntry);
      } catch (err) {
        console.log(
          'Unfortuantely there was an error in getting the data: ' +
            JSON.stringify(err)
        );
        console.log(err);
      }
    }
    fetchData();
  }, [phoneBookId]);

  const handleChange = (e, value) => {
    setItem({ ...item, surname: value });
  };

  const ContactCard = () => {
    return (
      <Fabric>
        <Stack>
          <Stack>
            <TextField
              label='name'
              required
              value={item.surname}
              onChange={handleChange}
            />
          </Stack>
        </Stack>
      </Fabric>
    );
  };

  if (!item) {
    return <div>Sorry, but that log was not found</div>;
  }

  return (
    <div>
      <ContactCard />
    </div>
  );
}

export default PhoneEntryFromRouter;

EDIT编辑

I have changed the handleChange function to make use of prevItem.我已经更改了 handleChange 函数以使用 prevItem。 For this event it does accept the event and a value.对于这个事件,它确实接受事件和一个值。 If you log that value out it is the current value and seems valid.如果您将该值注销,则它是当前值并且似乎有效。

Despite the change I am still seeing the loss of focus meaning I can only make a one key stroke edit each time.尽管发生了变化,但我仍然看到失去焦点,这意味着我每次只能进行一键式编辑。

    setItem((prevItem) => {
      return { ...prevItem, surname: e.target.value };
    });
  };```

I think you want the event.target 's value :我想你想要event.targetvalue

const handleChange = e => {
    setItem(prevItem => { ...prevItem, surname: e.target.value });
};

You should also notice that in your version of handleChange() , value is undefined (only the event e is being passed as a parameter).您还应该注意到,在您的handleChange()版本中, value undefined (只有事件e作为参数传递)。

Edit: Now I see that you're setting the value item with data from a fetch response on component mount.编辑:现在我看到您正在使用来自组件安装的 fetch 响应的数据设置值item Still, the value of item.surname is initially undefined, so I would consider adding a conditional in the value of the <TextField /> component:尽管如此, item.surname的值最初是未定义的,所以我会考虑在<TextField />组件的值中添加一个条件:

value={item.surname || ''}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM