javascript - React:如何在第一次渲染时跳过 useEffect
问题描述
我正在尝试使用useEffect
受控表单组件中的钩子在用户更改表单内容时通知父组件并返回表单内容的 DTO。这是我目前的尝试
const useFormInput = initialValue => {
const [value, setValue] = useState(initialValue)
const onChange = ({target}) => {
console.log("onChange")
setValue(target.value)
}
return { value, setValue, binding: { value, onChange }}
}
useFormInput.propTypes = {
initialValue: PropTypes.any
}
const DummyForm = ({dummy, onChange}) => {
const {value: foo, binding: fooBinding} = useFormInput(dummy.value)
const {value: bar, binding: barBinding} = useFormInput(dummy.value)
// This should run only after the initial render when user edits inputs
useEffect(() => {
console.log("onChange callback")
onChange({foo, bar})
}, [foo, bar])
return (
<div>
<input type="text" {...fooBinding} />
<div>{foo}</div>
<input type="text" {...barBinding} />
<div>{bar}</div>
</div>
)
}
function App() {
return (
<div className="App">
<header className="App-header">
<DummyForm dummy={{value: "Initial"}} onChange={(dummy) => console.log(dummy)} />
</header>
</div>
);
}
但是,现在效果是在第一次渲染时运行的,此时初始值是在挂载期间设置的。我该如何避免呢?
以下是加载页面并随后编辑这两个字段的当前日志。我也想知道为什么我会收到缺少依赖项的警告。
onChange callback
App.js:136 {foo: "Initial", bar: "Initial"}
backend.js:1 ./src/App.js
Line 118: React Hook useEffect has a missing dependency: 'onChange'. Either include it or remove the dependency array. If 'onChange' changes too often, find the parent component that defines it and wrap that definition in useCallback react-hooks/exhaustive-deps
r @ backend.js:1
printWarnings @ webpackHotDevClient.js:120
handleWarnings @ webpackHotDevClient.js:125
push../node_modules/react-dev-utils/webpackHotDevClient.js.connection.onmessage @ webpackHotDevClient.js:190
push../node_modules/sockjs-client/lib/event/eventtarget.js.EventTarget.dispatchEvent @ eventtarget.js:56
(anonymous) @ main.js:282
push../node_modules/sockjs-client/lib/main.js.SockJS._transportMessage @ main.js:280
push../node_modules/sockjs-client/lib/event/emitter.js.EventEmitter.emit @ emitter.js:53
WebSocketTransport.ws.onmessage @ websocket.js:36
App.js:99 onChange
App.js:116 onChange callback
App.js:136 {foo: "Initial1", bar: "Initial"}
App.js:99 onChange
App.js:116 onChange callback
App.js:136 {foo: "Initial1", bar: "Initial2"}
解决方案
您可以查看此答案,了解如何忽略初始渲染的方法。此方法用于useRef
跟踪第一次渲染。
const firstUpdate = useRef(true);
useLayoutEffect(() => {
if (firstUpdate.current) {
firstUpdate.current = false;
} else {
// do things after first render
}
});
至于您收到的警告:
React Hook useEffect 缺少依赖项:'onChange'
钩子调用 ( useEffect(() => {}, [foo]
) 中的尾随数组列出了钩子的依赖项。这意味着如果您在挂钩范围内使用一个变量,该变量可以根据组件的更改(例如组件的属性)而更改,则需要在此处列出。
推荐阅读
- c - C语言中EOF的使用
- matlab - 在网格上投影图像
- php - JQuery-Tabledit 一次只更新一列(我的代码有什么问题)
- c# - 转换为双 5.55111512312578E-17
- libreoffice - 在 LibreOffice Calc 中查找以匹配搜索条件的部分字符串
- apache-kafka - 在 kafka log.dir 配置中添加多个目录并为某些分区创建软链接。有什么不同?
- python - Python-对数字进行分类
- python - 给定公钥,PGP 在 Python 中加密输入文件
- c# - 如何处理可能不存在的 dll 依赖项?
- r - How to find the joint cumulative distribution function from a 2-D copula in R?