setState
是异步的
React 的 setState
是异步的,直接输出 payInfo
或者在 setTimeout
中输出payInfo
,都是null
import { useState } from 'react'
interface PayInfo {
amount?: number; // 需要支付的金额
id?: string;
}
const [payInfo, setPayInfo] = useState < PayInfo | null > (null);
init: (val: PayInfo) => {
setPayInfo(val);
setTimeout(() => {
console.log('payInfo', payInfo);
}, 10);
},
在 useEffect
中监听 payInfo
的变化,确保在 payInfo
更新之后再进行操作,而不是直接依赖 setTimeout
。
import { useState, useEffect } from 'react';
interface PayInfo {
amount?: number; // 需要支付的金额
id?: string;
}
const YourComponent = () => {
const [payInfo, setPayInfo] = useState<PayInfo | null>(null);
// init 方法
const init = (val: PayInfo) => {
setPayInfo(val);
};
// 监听 payInfo 更新后执行逻辑
useEffect(() => {
if (payInfo) {
// payInfo 更新后,这里的代码才会执行
console.log('payInfo has been updated:', payInfo);
}
}, [payInfo]); // 依赖 payInfo
return (
<div>
<button onClick={() => init({ amount: 100, id: '12345' })}>Set PayInfo</button>
</div>
);
};
export default YourComponent;
useImperativeHandle
useImperativeHandle
是 React 中一个很有用的钩子,它允许子组件暴露特定的方法给父组件,通常与 ref
一起使用。
子组件可以这样定义
import React, { useState, forwardRef, useImperativeHandle } from 'react';
interface MaterialsProps {
type?: string; // type 是一个字符串,传递给组件的参数
handleSelectItems?: (selectedItems: any[]) => void; // 父组件传递的方法
}
// 子组件定义看这行
const MaterialsPage: React.FC<MaterialsProps> = forwardRef(
({ type = 'default', handleSelectItems }, ref) => {
// 子组件接收的props参数解构,即 { type = 'default', handleSelectItems }
const [selectedItems, setSelectedItems] = useState<string[]>([]);
// 子组件中定义的 toggleAll 方法
const toggleAll = () => {
// 这里假设选中项的状态需要改变,举个例子
setSelectedItems((prev) =>
prev.length === 0 ? ['item1', 'item2', 'item3'] : []
);
};
// 暴露给父组件的方法
useImperativeHandle(ref, () => ({
toggleAll, // 父组件可以调用这个方法
}));
// 子组件调用父组件传递的方法
const handleItemClick = (item: string) => {
if (handleSelectItems) {
handleSelectItems(item);
}
};
return (
<div>
<p>Selected Items: {selectedItems.join(', ')}</p>
<button onClick={toggleAll}>Toggle All</button>
<div>
<button onClick={() => handleItemClick('item1')}>Select Item 1</button>
<button onClick={() => handleItemClick('item2')}>Select Item 2</button>
</div>
</div>
);
}
);
export default MaterialsPage;