You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Admin:如何通过SelectInput调用useStore设置全局变量?

解决React Admin中SelectInput同步useStore值的问题

你遇到的编译错误是因为React Admin的Filter组件会自动为内部输入组件绑定onChange事件来管理过滤表单状态,直接覆盖该事件会破坏默认的状态初始化逻辑。下面提供两种可行的解决方案:

方案一:监听List过滤状态同步到useStore

通过useListContext获取当前List组件的过滤参数,监听其变化并同步到useStore中,无需修改SelectInput的默认事件:

import React, { useEffect } from "react";
import {
  List,
  Datagrid,
  TextField,
  DateField,
  Filter,
  TextInput,
  SelectInput,
  useStore,
  useGetList,
  useListContext
} from "react-admin";

const SeatsFilter = (props) => {
  return (
    <Filter {...props}>
      <TextInput label="Name" source="name" alwaysOn />
      <SelectInput
        label="Select Election"
        source="electionCode"
        choices={props.allElections || []}
        alwaysOn
      />
    </Filter>
  );
};

const SeatsList = (props) => {
  const [electionCode, setElectionCode] = useStore("electionCode", "");
  const [allElections, setAllElections] = useStore("allElections", []);
  const { data } = useGetList("elections");
  const { filters } = useListContext();

  // 监听过滤参数中的electionCode变化,同步到useStore
  useEffect(() => {
    if (filters.electionCode !== undefined) {
      setElectionCode(filters.electionCode);
    }
  }, [filters.electionCode, setElectionCode]);

  useEffect(() => {
    setAllElections(data);
  }, [data]);

  return (
    <List
      filters={<SeatsFilter allElections={allElections || []} />}
      {...props}
      sort={{ field: "name", order: "asc" }}
    >
      <Datagrid rowClick="show">
        <TextField source="name" />
        <DateField source="updatedAt" label="Last Updated" />
      </Datagrid>
    </List>
  );
};

export default SeatsList;

方案二:自定义onChange同时更新表单和useStore

通过useFormContext获取Filter的表单上下文,在自定义的onChange中先执行React Admin的默认表单更新逻辑,再同步useStore的值:

import React, { useEffect } from "react";
import {
  List,
  Datagrid,
  TextField,
  DateField,
  Filter,
  TextInput,
  SelectInput,
  useStore,
  useGetList,
  useFormContext
} from "react-admin";

const SeatsFilter = ({ allElections, setElectionCode }) => {
  const { form } = useFormContext();

  const handleElectionChange = (value) => {
    // 先更新React Admin的过滤表单状态
    form.change("electionCode", value);
    // 再同步到useStore
    setElectionCode(value);
  };

  return (
    <Filter>
      <TextInput label="Name" source="name" alwaysOn />
      <SelectInput
        label="Select Election"
        source="electionCode"
        choices={allElections || []}
        alwaysOn
        onChange={handleElectionChange}
      />
    </Filter>
  );
};

const SeatsList = (props) => {
  const [electionCode, setElectionCode] = useStore("electionCode", "");
  const [allElections, setAllElections] = useStore("allElections", []);
  const { data } = useGetList("elections");

  useEffect(() => {
    setAllElections(data);
  }, [data]);

  return (
    <List
      filters={<SeatsFilter allElections={allElections || []} setElectionCode={setElectionCode} />}
      {...props}
      sort={{ field: "name", order: "asc" }}
    >
      <Datagrid rowClick="show">
        <TextField source="name" />
        <DateField source="updatedAt" label="Last Updated" />
      </Datagrid>
    </List>
  );
};

export default SeatsList;

关键说明

  • 方案一无需修改Filter内部逻辑,通过监听List的过滤状态实现同步,更符合React Admin的设计逻辑;
  • 方案二适合需要在选择时立即执行额外逻辑的场景,但必须确保先调用form.change维持默认过滤功能;
  • 原代码中TextField source="props.electionCode"是错误用法,source属性应对应数据字段名,若要展示当前选中的electionCode,可在SeatsList中通过electionCode变量直接渲染。

内容的提问来源于stack exchange,提问作者Joshua Foxworth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 13:05:22