改变 api 数据时反应选择更新值

pri*_*hak 3 reactjs react-select react-hooks react-query

我有一个反应选择组件,其中我从 api 数据归档选项,每当我从 api 编辑一个人的姓名时,选项中的名称会发生​​变化,但值上的名称保持不变。

我想在更改人名后更改 select 的值。

--这里我使用react-query更新一个人的名字

  const deliveryPersonUpdate = (values) => {
    const id = deliveryBoy && deliveryBoy.id;
    const params = { deliveryBoyId: id, ...values };
    updateDeliveryPerson.mutate(params, {
      onSuccess: (data) => {
        toggle();
        setDeliveryBoy(data?.delivery_boy);
        queryClient.invalidateQueries([GET_DELIVERY_BOY_LIST.name]);
        toast.success("Category Updated");
      },
      onError: (error) => {
        showErrorMessages({ error });
      },
    });
  };

  const handleSubmit = (values) => {
    deliveryPersonUpdate(values);
  };
Run Code Online (Sandbox Code Playgroud)

--选择组件

<Select
 onChange={(obj) => handleChange(obj)}
                paintBg
                noOptionsMessage={noOptionsMessage}
                name="deliveryBoySelect"
                className={cx(styles.addDeliveryBoySelect)}
                defaultValue={
                  !isEmpty(data?.delivery_boys) && {
                    label: data?.delivery_boys?.[0].name,
                    value: data?.delivery_boys?.[0].id,
                  }
                }
                options={data?.delivery_boys.map((d) => ({
                  label: d.name,
                  value: d.id,
                }))}
                isSearchable
              />
Run Code Online (Sandbox Code Playgroud)

--处理选择的更改

const handleChange = (e) => {
    const deliveryBoyData = data.delivery_boys.find(
      (obj) => obj.id === e.value
    );
    setDeliveryBoy(deliveryBoyData);
  };
Run Code Online (Sandbox Code Playgroud)

--这里,更改人名后,选项立即更新,但值没有更新 在此输入图像描述

Jak*_*lek 5

您面临的问题是您正在使用defaultValueselect ,这意味着 select不受控制。任何时候defaultValue更改,选择都不会对此更改做出反应,因为它不应该这样做,它只是默认值。

您有两个选择:

  1. 控制选择(通过使用状态)
  2. 使选择成为键控(通过在默认值更改时重新安装它)

至于受控选择

您必须替换defaultValuevalue,但还要附加一个onChange更改状态的处理程序。您已经拥有了,onChange因为它更新了 RQ 中的状态,但由于您正在使用defaultValue,所以它不会传播回来。但是,如果您刚刚使用,value我认为会出现闪烁,因为 RQ 本质上是异步的,因此用户可能会看到值仍然不同步的帧。因此,为了完全做到这一点,您还必须引入同步状态。

const [value, setValue] = useState(props.value)
const onChange = (e) => {
  setValue(e.target.value)
  props.onChange(e.target.value)
}
useEffect(() => {
  setValue(props.value)
}, [props.value])

<select value={value} onChange={onChange} />
Run Code Online (Sandbox Code Playgroud)

它的作用是使用 保持本地状态setState,使用 使用useEffect和 使用 来处理道具的更新value,而不是defaultValue感谢它。如有必要,您还可以提升状态。

至于键控组件

如果以前的解决方案不符合人体工程学或出于任何原因不好并且组件很小,您还可以决定不保留本地状态,而是卸载组件并安装新实例。结果是,当值发生变化时,它会安装一个新组件,以便可以defaultValue再次使用。除了添加道具之外,您保持选择不变key

<select key={props.value} defaultValue={props.value} onChange={onChange}>
Run Code Online (Sandbox Code Playgroud)

键与值相同意味着它们将同步。当本地值更改时,它不会闪烁,因为我们没有设置value,DOM 会自行更新,当props.value最终更改是通过 RQ 异步方式时,它会重新创建组件,使其与当前的defaultValue.