[英]Child component causing too many renderings on parent component when changing global state in React
我正在開發一個 React Web 應用程序,我有一個用於存儲一些數據的全局狀態,出於某種原因,我碰巧在我的應用程序上看到了不必要的渲染!
我有看起來像這樣的組件:
const LanguageSkills = () => {
const [languageSelected, setLanguage] = React.useState({})
const { dispatch } = useContext(GlobalStore)
const handleChange = (name: string) => (event: any) => {
setLanguage({ ...languageSelected, [name]: event.target.checked })
}
useEffect(() => {
dispatch({
type: ApplicantActions.FILTER_APPLICANTS,
payload: {
languageSkills: languageSelected,
},
})
}, [dispatch, languageSelected])
return (
<>
{
{languageSkills.map((lang, index) => (
<TermWrapper key={index}>
<GreenCheckbox onChange={handleChange(lang.term)} value="checked" />
<Term>{lang.term}</Term>
</TermWrapper>
))}
}
</>
)
}
這個組件導致父組件在沒有從這個組件做任何動作的情況下渲染,因為一旦組件被安裝(至少我知道),調度函數會立即在useEffect()內部調用,我還能如何處理這個所以只調度當我單擊單選按鈕時被調用? 一旦使用setState()更改本地狀態,是否有任何回調或某種方式可以調用 dispatch ?
知道在這種情況下如何使用調度嗎?
更新這一行
<GreenCheckbox onChange={handleChange(lang.term)} value="checked" />
對此
<GreenCheckbox onChange={() => handleChange(lang.term)} value="checked" />
您正在渲染時調用該函數。 給它一個回調
更新:
const handleChange = (name: string) => (event: any) => {
setLanguage({ ...languageSelected, [name]: event.target.checked })
}
useEffect(() => {
callMe();
}, [languageSelected])
const callMe = () => {
dispatch({
type: ApplicantActions.FILTER_APPLICANTS,
payload: {
languageSkills: languageSelected,
},
})
}
經過幾次嘗試,我想出了這個,對我來說似乎很好,不會導致父組件重新渲染!
const LanguageSkills = () => {
const [isVisible, setIsVisible] = useState(false)
const [state, setState] = React.useState({})
const { dispatch } = useContext(GlobalStore)
const handleChange = (name: string) => (event: React.ChangeEvent<HTMLInputElement>) => {
const obj = { ...state, [name]: event.target.checked }
dispatchLanguageFilter(obj)
setState({ ...state, [name]: event.target.checked })
}
const dispatchLanguageFilter = useCallback(
obj => {
const languageSkills: string[] = []
for (const [key, value] of Object.entries(obj)) {
if (value) {
languageSkills.push(key)
}
}
dispatch({
type: ApplicantActions.FILTER_APPLICANTS,
payload: {
languageSkills: languageSkills,
},
})
},
[dispatch],
)
return (
<>
<Wrapper onClick={() => setIsVisible(!isVisible)}>
<FilterContainerTitle>Kielitaito</FilterContainerTitle>
<Arrow>{!isVisible ? <ArrowDown /> : <ArrowUp />}</Arrow>
</Wrapper>
{isVisible && (
<>
{languageSkills.map((lang, index) => (
<TermWrapper key={index}>
<GreenCheckbox onChange={handleChange(lang.term)} value="checked" />
<Term>{lang.term}</Term>
<TotalAmountWrapper>
<TotalAmount>{lang.totalAmount}</TotalAmount>
</TotalAmountWrapper>
</TermWrapper>
))}
</>
)}
</>
)
}
不確定它是否正確,但任務完成了!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.