我正在寻找一种干净的方法来在自定义反应挂钩中存储几个简单的值。必须返回多个 setter 和 getter 感觉很不舒服。我可以为每个值传递一个值,即
const modalState = useState(false)
,然后引用 modalState[0] 和 [1],但这感觉很奇怪。 我不喜欢下面的函数的是它返回 10 个值。看起来好像很多。
function useNotesModal() {
const [showModal, setShowModal] = useState(false);
const [modalNoteId, setModalNoteId] = useState(0); // if 0, means create note in modal
const [modalNoteTitle, setModalNoteTitle] = useState("");
const [modalNoteDescription, setModalNoteDescription] = useState("");
const [modalNoteTagIds, setModalNoteTagIds] = useState([]);
return {
showModal,
setShowModal,
modalNoteId,
setModalNoteId,
modalNoteTitle,
setModalNoteTitle,
modalNoteDescription,
setModalNoteDescription,
modalNoteTagIds,
setModalNoteTagIds,
};
}
export default useNotesModal;
您可以批量返回值,例如 - 作为值和操作:
function useNotesModal() {
const [showModal, setShowModal] = useState(false);
const [modalNoteId, setModalNoteId] = useState(0); // if 0, means create note in modal
const [modalNoteTitle, setModalNoteTitle] = useState("");
const [modalNoteDescription, setModalNoteDescription] = useState("");
const [modalNoteTagIds, setModalNoteTagIds] = useState([]);
return {
values: {
showModal,
modalNoteId,
modalNoteTitle,
modalNoteDescription,
modalNoteTagIds
},
actions: {
setShowModal,
setModalNoteId,
setModalNoteTitle,
setModalNoteDescription,
setModalNoteTagIds,
}
};
}
另一种选择是通过
value
和 set
自动批处理:
const { useState, useEffect } = React;
function useNotesModal() {
const states = {
showModal: useState(false),
modalNoteId: useState(0),
modalNoteTitle: useState(""),
modalNoteDescription: useState(""),
modalNoteTagIds: useState([])
}
return Object.fromEntries(
Object.entries(states)
.map(([k, [value, set]]) => [k, { value, set }])
);
}
const Demo = () => {
const notesState = useNotesModal();
useEffect(() => {
setTimeout(() => {
notesState.modalNoteId.set(101);
}, 2000);
}, []);
console.log(notesState);
return <div>{notesState.modalNoteId.value}</div>;
}
ReactDOM.render(
<Demo />,
root
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>
一种可能的方法是仅使用单个对象来保存状态,并返回该对象的 setter。
类似:
function useNotesModal() {
const [state, setState] = useState({
showModal: false,
modalNoteId: 0,
modalNoteTitle: "",
modalNoteDescription: "",
modalNoteTagIds: [],
});
function setFieldState(fieldName, value){
setState({...state, [fieldName]: value});
}
return [state, setFieldState];
}
// Then, to use:
const [modalState, setModalState] = useNotesModal();
const showModal = modalState['showModal'];
setModalState("showModal", true);
这种情况下的关键是确保每次更新内部状态时都返回一个新对象。
另一种方法是:
function useNotesModal() {
const [showModal, setShowModal] = useState(false)
const [modalNoteId, setModalNoteId] = useState(0) // if 0, means create note in modal
const [modalNoteTitle, setModalNoteTitle] = useState('')
const [modalNoteDescription, setModalNoteDescription] = useState('')
const [modalNoteTagIds, setModalNoteTagIds] = useState([])
const notesModal = React.useRef()
if (notesModal.current === undefined) {
notesModal.current = {
showModal,
setShowModal,
modalNoteId,
setModalNoteId,
modalNoteTitle,
setModalNoteTitle,
modalNoteDescription,
setModalNoteDescription,
modalNoteTagIds,
setModalNoteTagIds
}
}
notesModal.showModal = showModal
notesModal.modalNoteId = modalNoteId
notesModal.modalNoteTitle = modalNoteTitle
notesModal.modalNoteDescription = modalNoteDescription
notesModal.modalNoteTagIds = modalNoteTagIds
return notesModal
}