首页 > 解决方案 > React.js - 使用不同设置多次使用一个组件

问题描述

我正在尝试创建一个可重用的组件,该组件包含类似的功能,其中唯一更改的是标题字符串和用于填充 Kendo ComboBox 的数据。

因此,我有一个导航菜单(目前)加载了六个不同的过滤器:

{ 
     context && context.Filters && context.Filters.map((item) => getComponent(item))
}

GetComponent 获取过滤器的 ID,从上下文中获取过滤器的定义,并创建一个下拉组件传入属性:

function getComponent(item) {
    var filterDefinition = context.Filters.find(filter => filter.Id === item.Id);

    switch (item.DisplayType) {
      case 'ComboBox':
        return <DropDownFilterable key={item.Id} Id={item.Id} Definition={filterDefinition} />
      default:
        return null;
    }
  }

DropDownFilterable 组件调用服务来获取组合框的数据,然后加载所有内容:

const DropDownFilterable = (props) => {
  const appService = Service();

  filterDefinition = props.Definition;
  console.log(filterDefinition.Name + " - " + filterDefinition.Id);

  React.useEffect(() => {
         console.log("useEffect: " + filterDefinition.Name + " - " + filterDefinition.Id);
         appService.getFilterValues(filterDefinition.Id).then(response => {
         filterData = response;
  })
}, []); 

  return (
    <div>
      <div className="row" title={filterDefinition.DisplayName}>{filterDefinition.DisplayName}</div>
      <ComboBox 
          id={"filterComboBox_" + filterDefinition.Id}
          data={filterData}
          //onOpen={console.log("test")}
          style={{zIndex: 999999}}
          dataItemKey={filterDefinition && filterDefinition.Definition && filterDefinition.Definition.DataHeaders[0]}
          textField={filterDefinition && filterDefinition.Definition && filterDefinition.Definition.DataHeaders[1]}
        />
    </div>
  )
}

服务电话:

  function getFilterValues(id) {
    switch(id) {
      case "E903B2D2-55DE-4FA3-986A-8A038751C5CD":
        return fetch(Settings.url_getCurrencies).then(toJson);
      default:
        return fetch(Settings.url_getRevenueScenarios).then(toJson);
    }
  };

发生的情况是,每个过滤器的标题 (DisplayName) 都正确呈现在导航菜单上,但所有六个过滤器的数据都是最后传入的过滤器的数据。我是 React 的新手,我对钩子还不是 100% 满意,所以我可能以错误的顺序做某事,或者没有在正确的钩子中做某事。我创建了一个精简版的应用程序:

https://codesandbox.io/s/spotlight-react-full-forked-r25ns

任何帮助,将不胜感激。谢谢!

标签: reactjs

解决方案


这是因为您使用filterData不正确 - 您在组件之外定义了它,DropDownFilterable这意味着它将被共享。相反,将值设置为组件状态(我已缩短代码以仅包含我的更改):

const DropDownFilterable = (props) => {
  // ...

  // store filterData in component state
  const [filterData, setFilterData] = React.useState(null);

  React.useEffect(() => {
    // ...
    appService.getFilterValues(filterDefinition.Id).then(response => {
      // update filterData with response from appService
      setFilterData(response);
    })
  }, []); 

  // only show a ComboBox if filterData is defined
  return filterData && (
    // ...
  )
}

或者,您可以使用空数组作为默认状态...

const [filterData, setFilterData] = React.useState([]);

...因为ComboBox组件接受data道具的数组。这样你就不必有条件地渲染。


更新

因为filterDefinition您还需要确保它设置正确:

const [filterDefinition, setFilterDefinition] = React.useState(props.Definition);

// ...

React.useEffect(() => {
  setFilterDefinition(props.Definition);
}, [props.Definition]);

filterDefinition如果您不希望它改变,那么保持状态也可能更容易:

const filterDefinition = props.Definition || {};

推荐阅读