問題の説明
// 举个栗子,我用hooks 写了这么一个组件
let Test = () => {
/** Search base infos */
const [searchID, setSearchID] = useState(0)
/** Search info action */
const onSearchInfos = useCallback(() => {
let fetchUrl = '/api/getSearchInfos'
let fetchParams = { searchID }
fetch(fetchUrl, {
method: 'POST',
body: JSON.stringify(fetchParams)
}).then(res => res.json()
).then(res => {
console.log(res)
})
}, [])
return (
<>
<button onClick={() => {setSearchID(searchID + 1)}} >button1</button>
<button onClick={() => {onSearchInfos()}}>button2</button>
</>
)
}
export default Test
すなわち、実質的に、ボタンクリックボタン1である、簡単な擬似コードの関数を書く、前記SearchId要求クリックボタン2を送信し、値1に加算されます。
問題を記述するために始めた:私たちは、要求が送信されることがわかります、その後、button2をクリックし、4にsearchIDの値を変更するには、ボタン1を4回をクリックすると、値searhIDは0です。
分析
なぜ、このような問題でしょうか?我々は、コールバックメソッドonSearchInfos useCallback要求データパッケージ層、及び第二パラメータを使用しているため、我々は、パフォーマンスを向上させるために[]、それは、コンポーネントが最初に作成された場合にのみ、コールバック関数が作成されていることを示し通過します!
レビューの下で、私はそれが何になると、上述しましたか?
最初のコンポーネントが作成されたときにのみ作成されOnSearchInfos!初めて!
まず、閉鎖を形成するために渡された値を作成したときには値を取得searchID。
ソリューション1
interface IRef {
current: any
}
let Test = () => {
/** Search base infos */
const [searchID, setSearchID] = useState(0)
/** 解决闭包问题 */
const fetchRef: IRef = useRef() // hooks为我们提供的一个通用容器,里面有一个current属性
fetchRef.current = { // 为current这个属性添加一个searchID,每当searchID状态变更的时候,Test都会进行重新渲染,从而current能拿到最新的值
searchID
}
/** Search info action */
const onSearchInfos = useCallback(() => {
let fetchUrl = '/api/getSearchInfos'
let fetchParams = { ...fetchRef.current } // 解构参数,这里拿到的是外层fetchRef的引用
fetch(fetchUrl, {
method: 'POST',
body: JSON.stringify(fetchParams)
}).then(res => res.json()
).then(res => {
console.log(res)
})
}, [])
return (
<>
<button onClick={() => {setSearchID(searchID + 1)}} >button1</button>
<button onClick={() => {onSearchInfos()}}>button2</button>
</>
)
}
export default Test
解決策2
解決策3
フォロー完璧な週末を見て、私の知る限りでは、少なくとも二つのソリューション、兄隣があり、ちょうど議論終え、勉強する時間がありませんでした!