更新状态对象不会重新渲染动态创建的组件

时间:2019-05-09 18:36:53

标签: javascript css reactjs state react-hooks

我有一个带有三个标签的组件,其中每个标签都有唯一的过滤器。我目前正在编写一个Filter组件,它将选项卡类型作为道具并呈现正确的filter按钮。单击每个按钮后,我希望按钮样​​式发生变化,以便用户知道他们已经设置了给定的过滤器。

我将每个按钮的状态存储在下面定义的对象中:

const [filterState, setFilterState] = useState({
    deployment: {
      running: false,
      success: false,
      warnings: false,
      failures: false,
    },
    health: {
      warnings: false,
      critical: false,
      errors: false,
    },
    task: {
      waiting: false,
      running: false,
      retrying: false,
      success: false,
      failures: false,
    }
  })

我有一个辅助函数,用于设置定义的filterType状态,如下所示:

  const setFilter = tab => {
    let updateFilter = filterState
    updateFilter[umsTab][tab] = !filterState[umsTab][tab]
    setFilterState(updateFilter)
    console.log(filterState[umsTab])
  }

我这样做是为了在每次调用此函数时完全更新对象状态。用于更新状态的函数由Button组件内的onClick方法调用。如上所述,这些按钮组件是动态创建的,就像这样:

const createButtons = () => {
    let FilterButtons = []

    FilterTypes[umsTab].forEach(tab => {
      FilterButtons.push(
        <Button
          kind={filterState[umsTab][tab] === false ? "primary" : "secondary"}
          key={tab}
          onClick={() => setFilter(tab)}
        >
          {tab}
        </Button>
      )
    })

    return FilterButtons
  }

单击按钮并在控制台中记录filterType状态变量,表明状态正在更新,但是组件未重新呈现。由于按钮是动态创建的,是否可以在此输入代码?我希望通过检查状态对象,可以在每次单击按钮时呈现带有或不具有样式的按钮。

完整代码:

const FilterTypes = {
  deployment: ["running", "success", "warnings", "failures"],
  health: ["warnings", "critical", "errors"],
  task: ["waiting", "running", "retrying", "success", "failures"],
}

const Filters = ({ umsTab }: Props) => {
  const { message } = useMessages()
  const [filterState, setFilterState] = useState({
    deployment: {
      running: false,
      success: false,
      warnings: false,
      failures: false,
    },
    health: {
      warnings: false,
      critical: false,
      errors: false,
    },
    task: {
      waiting: false,
      running: false,
      retrying: false,
      success: false,
      failures: false,
    },
  })

  const setFilter = tab => {
    let updateFilter = filterState
    updateFilter[umsTab][tab] = !filterState[umsTab][tab]
    setFilterState(updateFilter)
    console.log(filterState[umsTab])
  }

  const createButtons = () => {
    let FilterButtons = []

    FilterTypes[umsTab].forEach(tab => {
      FilterButtons.push(
        <Button
          kind={filterState[umsTab][tab] === false ? "primary" : "secondary"}
          key={tab}
          onClick={() => setFilter(tab)}
        >
          {tab}
        </Button>
      )
    })

    return FilterButtons
  }

  return <div>{createButtons()}</div>
}

1 个答案:

答案 0 :(得分:0)

尝试将createButtons方法重构为Component函数,并提供使用的字段作为属性。在渲染中调用函数时,React无法检查某些使用的值是否已更改,并且未正确更新ShadowDOM

const CreateButtons = ({filterTypes, filterState, umsTab}) => (
<React.Fragment>
    {filterTypes[umsTab].map(tab => (
        <Button
          kind={filterState[umsTab][tab] === false ? "primary" : "secondary"}
          key={tab}
          onClick={() => setFilter(tab)}
        >
          {tab}
        </Button>
      ))
    }
</React.Fragment>
)

和在过滤器中

return <div><CreateButtons filterTypes={FilterTypes} filterState={filterState} umsTab={umsTab}/></div>