【问题标题】:React change state from another component without passing setState method在不传递 setState 方法的情况下响应来自另一个组件的更改状态
【发布时间】:2022-02-22 22:41:21
【问题描述】:

我有一个自定义表格组件,它有两个道具:项目和列。我想实现一个排序功能。排序不是什么大问题。我正在对表组件内的项目进行排序,但是当对项目进行排序时,存储项目的状态也必须更改,这在我的表组件之外。我不想通过setState 方法,因为我的组件是通用的。如果我到处传递setState方法,那将非常没用。

流行的库如何在不需要传递状态更改方法的情况下解决这个问题?他们是否将状态复制到内部状态,然后对其进行修改?我希望我能解释我的问题。

【问题讨论】:

标签: reactjs react-hooks


【解决方案1】:

从controlled 与uncontrolled 组件的角度考虑可能会有所帮助。您可能从<input>s 等核心元素中对此很熟悉,您可以传入defaultValue 属性,让输入处理所有内容(“不受控制”),或者您可以传入value 和@987654326 @ 并自己处理事情(“受控”)。您也可以将表格组件设计为受控组件或非受控组件。

作为一个不受控制的组件,你可能会传入一个设置初始排序的道具,但之后一切都由表格处理。父级不会收到通知,也不会更新其状态:

const Parent = () => {
  const [items, setItems] = useState(/* some array */);

  return <MyTable items={items} defaultSort="asc" />
}

const MyTable = ({ items, defaultSort }) => {
  const [sort, setSort] = useState(defaultSort ?? 'asc');
  const sortedItems = useMemo(() => {
    if (sort === 'asc') {
      return [...items].sort(/* insert sort function here */)
    } else {
      return [...items].sort(/* insert sort function here */)
    }
  }, [items, sort]);

  return (
    <>
      <button onClick={() => setSort(sort === 'asc' ? 'dsc' : 'asc')}>
        Change Sort
      </button>
      {sortedItems.map(() => /* etc */)}
    </>
  )
}

如果你做一个受控组件,那么父母负责状态,孩子只是通知父母相关的变化

const Parent = () => {
  const [items, setItems] = useState(/* some array */);
  const [sort, setSort] = useState('asc');
  const sortedItems = useMemo(() => {
    if (sort === 'asc') {
      return [...items].sort(/* insert sort function here */)
    } else {
      return [...items].sort(/* insert sort function here */)
    }
  }, [items, sort]);

  return <MyTable items={sortedItems} onSortToggled={() => setSort(sort === 'asc' ? 'dsc' : 'asc')} />
}

const MyTable = ({ items, onSortToggled}) => {
  return (
    <>
      <button onClick={onSortToggled}>
        Change Sort
      </button>
      {items.map(() => /* etc */)}
    </>
  )
}

如果您添加一些额外的代码来检查未定义项,则可以使您的表同时支持受控和不受控模式,具体取决于传递的道具集。但它应该只是其中之一;您不应该尝试让两个组件同时管理状态,因为这只会增加状态不同步和引入错误的机会。

必须更改存储项目的状态,这在我的表格组件之外

如果这是您的要求之一,那么您基本上是在做受控组件版本,因此您必须接受父组件中描述如何执行此操作的函数。父组件是唯一知道自己拥有什么状态以及如何更新它的组件。

【讨论】:

  • 感谢您的回复。现在我更好地理解了这个概念。尝试从两个不同的组件管理状态真的很不方便。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-10
  • 2018-01-13
  • 2017-06-22
  • 2012-10-20
  • 2019-11-11
  • 1970-01-01
相关资源
最近更新 更多