我最近开始使用钩子,并且对“成员函数”有一个相对简单的问题。以前,成员函数在react类中是这样工作的:
class App extends React.Component {
constructor(props) {
this.state = { toggle: false };
this.toggle = this.toggle.bind(this);
}
// Member function
toggle() {
this.setState(toggle: !this.state.toggle);
}
render() {
<button onClick={this.toggle}>Toggle Me!</button>
}
}
但是,现在使用React Hooks,我没有使用class
组件,但是仍然需要一个函数来完成类似的工作。做这样的事情是不好的做法吗?如果是这样,这里的最佳做法是什么?
const App = () => {
const [toggle, setToggle] = useState(false);
// Kind of like a "member" function
const toggleState = () => setToggle(!toggle);
return <button onClick={toggleState}>Toggle Me!</button>;
}
答案 0 :(得分:3)
您的代码看起来不错。它适用于绝大多数情况,但是如果您想创建一个在渲染之间得到记忆的函数,则可以使用useCallback
钩子,例如发送到PureComponent
的道具将是相同的,不会引起不必要的渲染。
const { useState, useCallback, PureComponent } = React;
const App = () => {
const [toggle, setToggle] = useState(false);
const toggleState = useCallback(() => setToggle(toggle => !toggle), []);
return (
<div>
<div>{toggle ? 'On' : 'Off'}</div>
<VeryExpensiveComponent onClick={toggleState} />
</div>
);
};
class VeryExpensiveComponent extends PureComponent {
render() {
console.log("Rendered expensive component");
return <button onClick={this.props.onClick}>Toggle Me!</button>;
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
答案 1 :(得分:0)
这是一种正常的做法,但是当我们使用useEffect()
一些其他信息可以更好地为您编码
在自己的类中而不是在构造函数中设置状态:
class App extends Components {
state = { toggle: false };
}
最好将匿名函数用于“成员函数”,这样就不需要更多的bind()
免责声明:挂钩方法保持不变
import React, { Component } from 'react'
class App extends Component {
state = { toggle: false }
// Member function
toggle = () => {
// Todo
}
render() {
<button onClick={this.toggle}>Toggle Me!</button>
}
}
正确设置状态
当您依靠旧状态更新相同状态时,需要以这种方式定义状态。
import React, { Component } from 'react'
class App extends Component {
toggle = () => {
this.setState((prevState, props) => {
return { toggle: !prevState.toggle }
});
}
// render
}