[React] Safely setState on a Mounted React Component through
In the class version of this component,we had a method called? ? We want a "lock",which should run once when component inited,after component unmounted,it should be reseted. We can use ‘useRef‘ to build a container to hold our lock: const mountedRef = useRef(false); Then we can use useEffect: useEffect(() => { mountedRef.current = true return () => (mountedRef.current = false) },[]) The reason to use ‘[]‘ as second arguement,is because we don‘t want useEffect be triggered second times,we only want to run once,therefore,we use empty array,it won‘t trigger scecond time. ? Then we can create a safe setSetate function: const [state,setState] = useReducer( (state,newState) => ({...state,...newState}),{ loaded: false,fetching: false,data: null,error: null,},) const setSafeState = (...args) => mountedRef.current && setState(...args); ? ---- Full code: import {useContext,useReducer,useEffect,useRef} from ‘react‘ import PropTypes from ‘prop-types‘ import isEqual from ‘lodash/isEqual‘ import * as GitHub from ‘../../../github-client‘ function useSetState(initialState) { return useReducer( (state,initialState,) } function useSafeSetState(initialState) { const [state,setState] = useSetState(initialState) const mountedRef = useRef(false) useEffect(() => { mountedRef.current = true return () => (mountedRef.current = false) },[]) const safeSetState = (...args) => mountedRef.current && setState(...args) return [state,safeSetState] } function Query({query,variables,normalize = data => data,children}) { const client = useContext(GitHub.Context) const [state,setState] = useSafeSetState({ loaded: false,}) useEffect(() => { if (isEqual(previousInputs.current,[query,variables])) { return } setState({fetching: true}) client .request(query,variables) .then(res => setState({ data: normalize(res),loaded: true,}),) .catch(error => setState({ error,loaded: false,) }) const previousInputs = useRef() useEffect(() => { previousInputs.current = [query,variables] }) return children(state) } Query.propTypes = { query: PropTypes.string.isRequired,variables: PropTypes.object,children: PropTypes.func.isRequired,normalize: PropTypes.func,} export default Query (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |