Что мне нужно: в моем компоненте мне нужно показать счетчик загрузки при изменении значения из useContext. Я нашел решение, но оно мне не очень нравится.
const MyComponent = () => {
const { stateDB } = useDB // custom useContext hook
// stateDB is an array of objects
const [loading, setLoading] = useState(false)
useEffect(() => {
// I need to show loading each time the stateDB changes
// but not each time the component will mount
setLoading(true)
setTimeout(() => {
setLoading(false)
}, 2000)
}, [stateDB])
return(
<>
{ loading ? <LoadingComponent/> : {stateDB.someValue} }
</>
)
}
Если я сделаю это так, то useEffect будет вызываться каждый раз, когда компонент будет монтироваться, даже если stateDB не будет изменен. Итак, мой вопрос: есть ли способ вызвать этот useEffect только тогда, когда значение из useContext изменится? Так как хук useContext каждый раз возвращает новый объект, то useEffect считает его отличным от предыдущего.
Внутри useDB у меня есть:
const DBContext = React.createContext();
export const useDB = () => {
return useContext(DBContext);
}
export const DBProvider = ({children}) => {
// the state i need in my component
const [ state, setState ] = useState([]) // default empty array
const fetchSomeData = async () => {
const response = await db...// fetchin data here
.then( () => setState(fetchedData) )
return () => response()
}
useEffect( () => {
fetchSomeData() // fetch the data only once
}, [])
value = { state } // the state I need in my component
return <DBContext.Provider value={value}>
{children}
</DBContext.Provider>
}
решение, которое я нашел:
// in my component
let flag = true;
const MyComponent = () => {
const { stateDB } = useDB
const [loading, setLoading] = useState(false)
useEffect( () => {
if (flag) {
flag = false;
setLoading(true)
setTimeout(() => {
setLoading(false)
}, 1200)
}
}, [flag])
return(
<>
{ loading ? <LoadingComponent/> : {stateDB.someValue} }
</>
)
}
useDB
- person Dupocas   schedule 15.11.2020useDB
- person Dupocas   schedule 15.11.2020useContext
, когда на самом деле вы спрашиваете, как предотвратить запускuseEffect
при первоначальном рендеринге, который вы уже обнаружили для себя. Хотя лучше использоватьuseRef
, чтобы все было удобно для React - см. on-the-initial-render">эта тема. В качестве альтернативы, почему бы просто не инициализироватьstate
каким-нибудь нейтральным значением, напримерnull
, с которым можно свериться при первом рендеринге? - person lawrence-witt   schedule 15.11.2020