React Custom Hook 函数不读取反冲 Atom
React Custom Hook function is not reading recoil Atom
我正在尝试在 React 项目中使用 formik、typescript 和 recoil 创建一个多请求、多步骤的表单。我已经创建了一个自定义挂钩,它具有 returns 三个功能,其中一个需要它正在使用的模型的特定 UUID,以便它可以发出 PUT 请求。当我用另一个相同的钩子函数发出 POST 请求时,这个 UUID 被设置为 Recoil Atom,然后我尝试在它下面的函数中访问它,但它没有正确显示。我试图等待它并将它分配给一个变量,但无济于事,当我在函数外部记录它时状态 returns 我需要的值,但是当我在函数内部记录它时(我需要它的地方)是),它是空的。我试图避免使用本地存储,因为这意味着要管理另一种类型的数据,这可能会破坏我程序的其余部分。
这是钩子:
const useInstitution = () => {
const setCurrentId = useSetRecoilState(institutionId);
const currentId = useRecoilValue(institutionId);
console.log(currentId);
// The above line properly logs the UUID I want
const handleValues = useCallback((values: InstitutionFormType) => {
return {
...values,
institution_registered_number: values.institution_registered_number.replace(/\D+/g, ''),
institution_id: currentId || values.institution_id,
};
}, [currentId]);
const insertInstitution = useCallback(async (values, callback) => {
const newValues = handleValues(values);
const {
institution_logo_file,
} = newValues;
const response = await createInstitution(newValues);
setCurrentId(response?.data.institution_id);
}, [handleValues, setCurrentId]);
const institutionEdit = useCallback(async (values, callback) => {
const newValues = handleValues(values);
console.log(currentId);
// This line logs an empty value
}, [currentId, handleValues]);
return {
insertInstitution, institutionEdit, currentId,
};
};
export default useInstitution;
这就是原子:
export const institutionId = atom({
key: 'institutionId',
default: '',
});
在这个钩子中,当 createInstitution 请求被调用并成功时,id 被设置为 Recoil Atom institutionId,并且我尝试将其记录在两行不同的行中,一行在函数之外,另一行在函数 institutionEdit 内,例如:
第一行是 console.log 函数外部和钩子内部的日志。第二行是institutionEdit函数里面的console.log.
为什么会这样?如何在钩子函数中正确访问它?
useSetRecoilState 文档指出
Returns a setter function which can be used asynchronously to change the state. The setter may either be passed a new value or an updater function which receives the previous value as an argument.
状态由 useSetRecoilState
返回的 setter 异步更改。为了在更新后的状态下执行某些操作,您应该使用 useEffect
来监视更改和 运行 所需的代码。
参见下面的示例。
const {
useCallback,
useEffect,
useContext,
} = React;
const {
RecoilRoot,
atom,
useSetRecoilState,
useRecoilValue
} = Recoil;
const institutionId = atom({
key: 'institutionId',
default: '',
});
const createInstitution = () => new Promise(res => setTimeout(() => res({
data: {
institution_id: Math.round(Math.random() * 50)
}
}), 1500))
const useInstitution = () => {
const setCurrentId = useSetRecoilState(institutionId);
const currentId = useRecoilValue(institutionId);
console.log(currentId);
// The above line properly logs the UUID I want
const handleValues = useCallback((values: InstitutionFormType) => {
return {
...values,
institution_registered_number: values.institution_registered_number.replace(/\D+/g, ''),
institution_id: currentId || values.institution_id,
};
}, [currentId]);
const insertInstitution = useCallback((values, callback) => {
const newValues = handleValues(values);
const {
institution_logo_file,
} = newValues;
createInstitution(newValues).then(response =>
setCurrentId(response && response.data.institution_id));
}, [handleValues, setCurrentId]);
const institutionEdit = useCallback((values, callback) => {
const newValues = handleValues(values);
console.log(currentId);
// This line logs an empty value
}, [currentId, handleValues]);
return {
insertInstitution,
institutionEdit,
currentId,
};
};
const insts = new Array(10).fill().map((v, i) => ({
institution_logo_file: 'logo 1',
institution_registered_number: `reg no ${i}`
}))
const App = () => {
const {
insertInstitution,
institutionEdit,
currentId,
} = useInstitution();
useEffect(() => {
insertInstitution(insts[0])
}, [])
// Getting the recoil state value
const recoilValue = useRecoilValue(institutionId)
useEffect(() => {
institutionEdit(insts[0])
}, [institutionEdit, recoilValue]) // execute only when `recoilValue` changes
console.log(recoilValue)
return ( < div > Hi < /div>)
}
ReactDOM.render( < RecoilRoot > < App / > < /RecoilRoot> , document.querySelector('#root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/recoil@0.3.1/umd/recoil.min.js"></script>
<div id="root" />
我正在尝试在 React 项目中使用 formik、typescript 和 recoil 创建一个多请求、多步骤的表单。我已经创建了一个自定义挂钩,它具有 returns 三个功能,其中一个需要它正在使用的模型的特定 UUID,以便它可以发出 PUT 请求。当我用另一个相同的钩子函数发出 POST 请求时,这个 UUID 被设置为 Recoil Atom,然后我尝试在它下面的函数中访问它,但它没有正确显示。我试图等待它并将它分配给一个变量,但无济于事,当我在函数外部记录它时状态 returns 我需要的值,但是当我在函数内部记录它时(我需要它的地方)是),它是空的。我试图避免使用本地存储,因为这意味着要管理另一种类型的数据,这可能会破坏我程序的其余部分。
这是钩子:
const useInstitution = () => {
const setCurrentId = useSetRecoilState(institutionId);
const currentId = useRecoilValue(institutionId);
console.log(currentId);
// The above line properly logs the UUID I want
const handleValues = useCallback((values: InstitutionFormType) => {
return {
...values,
institution_registered_number: values.institution_registered_number.replace(/\D+/g, ''),
institution_id: currentId || values.institution_id,
};
}, [currentId]);
const insertInstitution = useCallback(async (values, callback) => {
const newValues = handleValues(values);
const {
institution_logo_file,
} = newValues;
const response = await createInstitution(newValues);
setCurrentId(response?.data.institution_id);
}, [handleValues, setCurrentId]);
const institutionEdit = useCallback(async (values, callback) => {
const newValues = handleValues(values);
console.log(currentId);
// This line logs an empty value
}, [currentId, handleValues]);
return {
insertInstitution, institutionEdit, currentId,
};
};
export default useInstitution;
这就是原子:
export const institutionId = atom({
key: 'institutionId',
default: '',
});
在这个钩子中,当 createInstitution 请求被调用并成功时,id 被设置为 Recoil Atom institutionId,并且我尝试将其记录在两行不同的行中,一行在函数之外,另一行在函数 institutionEdit 内,例如:
第一行是 console.log 函数外部和钩子内部的日志。第二行是institutionEdit函数里面的console.log.
为什么会这样?如何在钩子函数中正确访问它?
useSetRecoilState 文档指出
Returns a setter function which can be used asynchronously to change the state. The setter may either be passed a new value or an updater function which receives the previous value as an argument.
状态由 useSetRecoilState
返回的 setter 异步更改。为了在更新后的状态下执行某些操作,您应该使用 useEffect
来监视更改和 运行 所需的代码。
参见下面的示例。
const {
useCallback,
useEffect,
useContext,
} = React;
const {
RecoilRoot,
atom,
useSetRecoilState,
useRecoilValue
} = Recoil;
const institutionId = atom({
key: 'institutionId',
default: '',
});
const createInstitution = () => new Promise(res => setTimeout(() => res({
data: {
institution_id: Math.round(Math.random() * 50)
}
}), 1500))
const useInstitution = () => {
const setCurrentId = useSetRecoilState(institutionId);
const currentId = useRecoilValue(institutionId);
console.log(currentId);
// The above line properly logs the UUID I want
const handleValues = useCallback((values: InstitutionFormType) => {
return {
...values,
institution_registered_number: values.institution_registered_number.replace(/\D+/g, ''),
institution_id: currentId || values.institution_id,
};
}, [currentId]);
const insertInstitution = useCallback((values, callback) => {
const newValues = handleValues(values);
const {
institution_logo_file,
} = newValues;
createInstitution(newValues).then(response =>
setCurrentId(response && response.data.institution_id));
}, [handleValues, setCurrentId]);
const institutionEdit = useCallback((values, callback) => {
const newValues = handleValues(values);
console.log(currentId);
// This line logs an empty value
}, [currentId, handleValues]);
return {
insertInstitution,
institutionEdit,
currentId,
};
};
const insts = new Array(10).fill().map((v, i) => ({
institution_logo_file: 'logo 1',
institution_registered_number: `reg no ${i}`
}))
const App = () => {
const {
insertInstitution,
institutionEdit,
currentId,
} = useInstitution();
useEffect(() => {
insertInstitution(insts[0])
}, [])
// Getting the recoil state value
const recoilValue = useRecoilValue(institutionId)
useEffect(() => {
institutionEdit(insts[0])
}, [institutionEdit, recoilValue]) // execute only when `recoilValue` changes
console.log(recoilValue)
return ( < div > Hi < /div>)
}
ReactDOM.render( < RecoilRoot > < App / > < /RecoilRoot> , document.querySelector('#root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/recoil@0.3.1/umd/recoil.min.js"></script>
<div id="root" />