在这个例子中,我有这个反应类:
class MyDiv extends React.component
constructor(){
this.state={sampleState:'hello world'}
}
render(){
return <div>{this.state.sampleState}
}
}
问题是我是否可以添加React钩子。我知道React-Hooks是React Class风格的替代品。但是如果我想慢慢迁移到React钩子,我可以在Classes中添加有用的钩子吗?
类组件不支持挂钩 -
根据Hooks-FAQ:
你不能在类组件中使用Hooks,但你绝对可以在一棵树中将Hook和类和函数组件混合在一起。组件是类还是使用Hook的函数是该组件的实现细节。从长远来看,我们希望Hooks成为人们编写React组件的主要方式。
High order components是我们一直在做这种事情,直到钩子出现。您可以为钩子编写一个简单的高阶组件包装器。
function withMyHook(Component) {
return function WrappedComponent(props) {
const myHookValue = useMyHook();
return <Component {...props} myHookValue={myHookValue} />;
}
}
虽然这不是真正直接从类组件使用钩子,但这至少允许您从类组件中使用钩子的逻辑,而无需重构。
class MyDiv extends React.Component {
render(){
const myHookValue = this.props.myHookValue;
return <div>{myHookValue}</div>;
}
}
MyDiv = withMyHook(MyDiv);
钩子不是用于类而是用于函数。如果您希望使用钩子,可以先将新代码编写为带钩子的功能组件
你不能在类组件中使用Hooks,但你绝对可以在一棵树中将Hook和类和函数组件混合在一起。组件是类还是使用Hook的函数是该组件的实现细节。从长远来看,我们希望Hooks成为人们编写React组件的主要方式。
const MyDiv = () => {
const [sampleState, setState] = useState('hello world');
render(){
return <div>{sampleState}</div>
}
}
正如其他答案已经解释的那样,hooks API旨在为功能组件提供当前仅在类组件中可用的功能。钩子不应该用在类组件中。
可以编写类组件,以便更容易地迁移到功能组件。
单一状态:
class MyDiv extends Component {
state = {sampleState: 'hello world'};
render(){
const { state } = this;
const setState = state => this.setState(state);
return <div onClick={() => setState({sampleState: 1})}>{state.sampleState}</div>;
}
}
转换为
const MyDiv = () => {
const [state, setState] = useState({sampleState: 'hello world'});
return <div onClick={() => setState({sampleState: 1})}>{state.sampleState}</div>;
}
请注意,useState
状态setter不会自动合并状态属性,这应该用setState(prevState => ({ ...prevState, foo: 1 }))
覆盖;
有多个州:
class MyDiv extends Component {
state = {sampleState: 'hello world'};
render(){
const { sampleState } = this.state;
const setSampleState = sampleState => this.setState({ sampleState });
return <div onClick={() => setSampleState(1)}>{sampleState}</div>;
}
}
转换为
const MyDiv = () => {
const [sampleState, setSampleState] = useState('hello world');
return <div onClick={() => setSampleState(1)}>{sampleState}</div>;
}
有状态的组件或容器或基于类的组件都支持React Hooks的功能,因此我们不需要在无状态组件中的状态组件中使用React Hooks。
一些额外的信息
什么是React Hooks?那么钩子是什么?井钩是一种新方式或为我们提供一种编写组件的新方法。
到目前为止,我们当然有功能和基于类的组件,对吧?功能组件接收道具并返回一些应该呈现给屏幕的JSX代码。
它们非常适合演示,因此,为了呈现UI部分,而不是业务逻辑,它们通常专注于每个组件的一个或几个目的。
另一方面,基于类的组件也将接收道具,但它们也具有此内部状态。因此,基于类的组件是实际占用我们业务逻辑的大部分组件,因此对于业务逻辑,我的意思是我们发出HTTP请求,我们需要处理响应并更改应用程序的内部状态或者即使没有HTTP。用户填写表单,我们希望在屏幕上显示这个,我们需要状态,我们需要基于类的组件,因此我们通常也使用基于类的组件来编排我们的其他组件并将我们的状态传递下去例如,作为功能组件的道具。
现在我们遇到了这个分离的一个问题,它增加了所有的好处,但我们遇到的一个问题是从一个组件形式转换到另一个组件形式是令人讨厌的。这不是很难,但很烦人。
如果你发现自己处于需要将功能组件转换为基于类的组件的情况下,那就是大量的输入和大量的输入总是相同的事情,所以这很烦人。
引号中一个更大的问题是生命周期钩子很难正确使用。
显然,添加componentDidMount并在那里执行一些代码并不难,但要知道使用哪个生命周期钩子,何时以及如何正确使用它,这可能是一个挑战,特别是在更复杂的应用程序中,无论如何,如果我们不是很好有一种创建组件的方法,然后超级组件可以处理状态和副作用,如HTTP请求,还可以呈现用户界面?
嗯,这正是钩子的全部内容。钩子为我们提供了一种创建功能组件的新方法,这很重要。
使用现有的类组件是不可能的。您必须将类组件转换为功能组件,然后执行以下操作:
function MyDiv() {
const [sampleState, setSampleState] = useState('hello world');
return (
<div>{sampleState}</div>
)
}