reactjs - React Hooks 和 React 生命周期方法
问题描述
我是 reactjs 的新手,并且对本机做出反应。当开始学习基础知识时,我发现了关于反应钩子和反应生命周期方法的各种信息。我知道在 react 16.3 之前有 7 个生命周期方法,但现在只有 6 个。任何人都可以详细说明此生命周期方法并通过一些示例对钩子做出反应。这可能有助于我学得更快。谢谢
解决方案
在 React 类中,你有生命周期函数和状态来做事,但你没有在函数组件中拥有它们。React defs 提出了钩子,通过在自定义钩子中捆绑某些功能,您可以简化代码并更好地重用代码。这在以前的类组件中是不可能的。即使使用了 Vue 中使用的 mix-ins,它们现在也拥有与 hooks 类似的组合 api。
假设您想要具有计数器功能,当计数器更改时会记录,具有向上和向下功能和计数器值。
在一个类中,您需要维护您使用 this.up 和 this.down 更改的 this.state.counter,以便您可以在扩展 React.Component 或 React.PureComponent 的 Counter 类中实现它,并拥有一个使用计数器的组件扩展计数器,但该组件仍然可以只有一个计数器。在钩子中,您可以使用自定义钩子实现一个计数器,并在一个组件中拥有多个计数器。
const {
useState,
useEffect,
useCallback,
useRef,
memo,
} = React;
//hooks, also custom hooks always start with "use"
const useCounter = (name, initialValue = 1) => {
//local counter value and function to change it
const [counter, setCounter] = useState(initialValue);
//ref created on mount with previous counter value
const countRef = useRef(initialValue);
//up and down functions created with useCallback so they
// will be created on mount and never change
const up = useCallback(
() => setCounter((c) => c + 1),
[]
);
const down = useCallback(
() => setCounter((c) => c - 1),
[]
);
//effect that will log when counter changes
useEffect(() => {
if (countRef.current !== counter) {
console.log(`counter ${name} changed to`, counter);
countRef.current = counter;
}
}, [counter, name]);
//return up, down and counter
return { up, down, counter };
};
//using memo makes UP2 a pure component so it'll not re
// render since up is created with useCallback and is
// not re created therefore the props passed to UP2
// don't change
const UP2 = memo(function UP2({ up, name }) {
console.log(`UP2 for ${name} will only render once`);
return (
<button
onClick={() => {
//state updates are batched in synchronous
// event handlers so "chaged to" will log
// only once
up();
up();
}}
>
+2
</button>
);
});
const App = () => {
//first counter
const {
up: up1,
down: down1,
counter: counter1,
} = useCounter('counter one');
//second counter
const {
up: up2,
down: down2,
counter: counter2,
} = useCounter('counter two', 2);
return (
<div>
<div>
<button onClick={up1}>UP</button>
<button onClick={down1}>Down</button>
<UP2 up={up1} name={'counter one'} />
{counter1}
</div>
<div>
<button onClick={up2}>UP</button>
<button onClick={down2}>Down</button>
<UP2 up={up2} name={'counter two'} />
{counter2}
</div>
</div>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
推荐阅读
- python-3.x - 如何根据某些标准从一组中找到与我的测试项目最相似的项目?
- javascript - Html & js 不显示图片
- ios - 如何根据构建配置将命令行参数传递给 Xcode
- java - 嗨,我可以打印变量名吗?
- r - 将 Base64 解码为数据帧
- mysql - 我的 TRIGGER sql 语句有什么问题 - MySQL
- javascript - 用于单击 css 的锚标记的border-bottom
- android - 如何在 Android Studio 中获取原始资源的文件路径?
- node.js - MVC 中的 NodeJS Express 密码重置
- c# - 如何使用 fiddler c# 在系统代理设置中包含绕过 URL 的列表