Reactjs 将类组件转换为函数组件

Reactjs 将类组件转换为函数组件,reactjs,react-hooks,Reactjs,React Hooks,下面是一些代码的示例 我试图找出如何将主类更改为功能组件,但我一直在研究如何转换 setCategory(category) { this.setState({ displayCategory: category }); } 第72-76行 有人对如何做到这一点有什么建议吗?我是一个新的反应者,我试图找出最好的方法来做这件事。在功能组件中,您有可以用于此目的的挂钩。可以使用初始化状态变量。在functional component中,代码段看起来像这样- con

下面是一些代码的示例

我试图找出如何将主类更改为功能组件,但我一直在研究如何转换

setCategory(category) {
    this.setState({
      displayCategory: category
    });
  }
第72-76行


有人对如何做到这一点有什么建议吗?我是一个新的反应者,我试图找出最好的方法来做这件事。

在功能组件中,您有可以用于此目的的挂钩。可以使用初始化状态变量。在functional component中,代码段看起来像这样-

const [displayCategory, setDisplayCategory] = useState('defaultStateValue');
const setCategory = (category) => {
    setDisplayCategory(category);
}
在上面的代码片段中,您只是使用
useState()
hook初始化状态变量和状态变量setter函数。然后调用
setDisplayCategory()
并将希望状态变量
displayCategory
更新到的参数传递给它。您应该以类似的方式初始化
Main
组件中的所有其他状态变量


您应该在这里阅读更多关于钩子的内容,并熟悉这些钩子,因为它经常用于功能组件中,

状态方法可以替换为

我建议你检查一下文件,但要记住的要点是

  • 没有
    这个
    (因此不再有
    .bind(这个)
    !)
  • 一切都是功能
还有钩子的规则

  • 钩子只能从react函数调用(不能从普通的
    js
    函数调用)。也就是说,从功能组件或其他挂钩调用它们
  • 钩子的调用顺序必须始终相同,这意味着您不能有条件地调用钩子(比如在
    if
    中)或在循环中)。因此,它们也必须在组件的“顶层”级别被调用(也就是说,它们不能在组件中定义的函数内被调用)
考虑到这一点,让我们看看你将如何取代国家。为此,可以使用
useState
hook

const [displayCategory, setDisplayCategory] = useState('all');
唯一参数是状态的初始值。此选项是可选的,如果未提供默认值,则与提供未定义的
相同
如您所见,它返回一个由两个元素组成的数组,我们在这里所做的是解构;这和做同样的事

const stateHook = useState('all')
const displayCategory = stateHook[0]
const setDisplayCategory= stateHook[1]
这意味着你可以命名任何你想要的变量。 现在,
displayCategory
是您的实际状态值。您可以像使用
this.state.displayCategory一样使用它。
setDisplayCategory
是一个可以更新状态的函数

要记住的一个区别是,钩子中更新状态的函数将覆盖整个状态,这意味着不会像类中那样合并状态。这对于对象尤其重要。像这样的

const [state, setState] = useState({ foo: 1, baz: 2 })
// later in one event
setState({ baz: 3 })
const [displayCategory, setDisplayCategory] = useState('all')
const [products, setProducts] = useState([])
const [myComplexObject, setMyComplexObject] = useState({ foo: 1, baz: 2, bar: [1, 2, 3] })
在那里,在下一次渲染时,
state
的值将是
{baz:3}
-前一个值丢失

为了保留状态,从
useState
返回的数组中的第二个参数(意思是
setState
setDisplayCategory
,或您所称的任何参数)接受一个回调,您可以在其中手动合并属性。像这样

setState(prevState => ({ ...prevState, baz: 3 })
现在,在下一次渲染中,状态的值将是
{foo:1,baz 3}

复杂状态建模

在hooks之前,您只能有一个状态。因此,您想要在您的状态中存储的所有内容都必须属于这个独特的对象。但是,使用钩子,可以有多个状态。例如,按照您的代码,您可以有如下内容

const [state, setState] = useState({ foo: 1, baz: 2 })
// later in one event
setState({ baz: 3 })
const [displayCategory, setDisplayCategory] = useState('all')
const [products, setProducts] = useState([])
const [myComplexObject, setMyComplexObject] = useState({ foo: 1, baz: 2, bar: [1, 2, 3] })

考虑到这一点,以及属性不会自动合并的事实,可以方便地将状态对象/变量/属性分组到同一
useState
对象下。这提供了更大的灵活性,特别是在将状态的不同部分传递给不同的子组件时——如果这些组件的道具不变,则可以保存一些重新渲染的程序

感谢您的详细响应。到目前为止,这对我来说似乎是有意义的,可能是因为在我的示例中使用了大量的组件,所以我感到困惑。我试着跟进:我不知道为什么这些产品现在没有出现。我更习惯于使用类组件,因此我很抱歉,这对我来说还不是全部。您缺少传递一些道具(UI组件没有收到任何东西),并且您必须从
react
执行导入
useState
(这是一个命名导出)