javascript - 有没有更简洁的方法在顶层定义 React Hooks useState?
问题描述
我有一个具有很多状态属性的向导组件。它用于保存大约 5 页内容的状态,然后控制向 api 的提交。
在第一个示例中,我遵守了使用 React Hooks 的第一条规则。
1. 只在顶层调用 Hooks
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
const Wizard = props => {
const [uuid, setUuid] = useState(props.uuid)
const [firstName, setFirstName] = useState('')
const [lastName, setLastName] = useState('')
const [address1, setAddress1] = useState('')
const [address2, setAddress2] = useState('')
const [address3, setAddress3] = useState('')
const [addressState, setAddressState] = useState('')
//etc for many
return (
<div>
{/*
<Page1 firstName={firstName} secondName={secondName} />
//...more pages
*/}
</div>
)
}
ReactDOM.render(<Wizard uuid={123} />, document.getElementById('root'))
我认为组件设置有点冗长,所以我想将所有useState
调用放在不同的函数中(最终移动到单独的文件)并让它返回state
and setters
.
import React from 'react'
import ReactDOM from 'react-dom'
const generateState = props => {
const [uuid, setUuid] = useState(props.uuid)
const [firstName, setFirstName] = useState('')
const [lastName, setLastName] = useState('')
const [address1, setAddress1] = useState('')
const [address2, setAddress2] = useState('')
const [address3, setAddress3] = useState('')
const [addressState, setAddressState] = useState('')
//etc for many
return {
state: {
firstName,
//etc
},
setters: {
setFirstName,
//etc
}
}
}
const Wizard = props => {
const {
state,
setters
} = generateState(props)
return (
<div>
{/*
<Page1 firstName={state.firstName} secondName={state.secondName} />
//...more pages
*/}
</div>
)
}
ReactDOM.render(<Wizard uuid={123}/>, document.getElementById('root'))
第二个例子违反了第一条规则,如果“这些就是规则!”,我想这很好。我的问题是,是否有一种更简洁的方法来定义useState
组件顶部的调用并避免错误:?
React Hook "useState" is called in function "generateState" which is neither a React function component or a custom React Hook function react-hooks/rules-of-hooks
注意:我希望状态在组件中,而不是在其他地方(即 Redux)
解决方案
你得到的 Lint 错误是因为你没有遵循反应指南来创建自定义钩子而不是命名generateState
使用useGenerateState
linter 错误不会出现。
您在第二部分中所做的是创建自定义钩子,只有当您希望它更清洁时才正确使用仅使用useReducer
钩子。
检查这个参考:
https://reactjs.org/docs/hooks-rules.html#eslint-plugin
https://reactjs.org/docs/hooks-custom.html#extracting-a-custom-hook
该案例代码将没有 linter 错误:
import React from 'react';
import ReactDOM from 'react-dom';
const useGenerateState = props => {
const [uuid, setUuid] = useState(props.uuid)
const [firstName, setFirstName] = useState('')
const [lastName, setLastName] = useState('')
const [address1, setAddress1] = useState('')
const [address2, setAddress2] = useState('')
const [address3, setAddress3] = useState('')
const [addressState, setAddressState] = useState('')
//etc for many
return {
state: {
firstName,
//etc
},
setters: {
setFirstName,
//etc
}
}
}
const Wizard = props => {
const {
state,
setters
} = useGenerateState(props)
return (
<div>
{/*
<Page1 firstName={state.firstName} secondName={state.secondName} />
//...more pages
*/}
</div>
)
}
ReactDOM.render(<Wizard uuid={123}/>, document.getElementById('root'))
推荐阅读
- ios - “无法检查应用程序包”。当我将任何 pod 添加到我的工作区时
- visual-studio-code - 如何在 Visual Studio Code 中关闭这些无用信息?
- python - 如何在 Tkinter 中“打印”控制台日志?
- python - 如果没有显示帖子,我该如何发布消息?
- java - Java 版本与 Protobuf 冲突
- .net - 通过批处理脚本为所有用户设置语言
- python - PyTorch:如何使用循环将张量附加到列表中
- javascript - dataTable 单元格可编辑 onclick 并在没有按钮的情况下按下输入键
- python - 在 django 模板中比较模型中的选择字段
- jquery - jQuery 单击此,隐藏其他 div,展开以显示当前 div 中的内容,再次单击以显示其他 div 并将其返回到原始大小/位置