Bunu, bileşenlerinize ne zaman oluşturulacağını söylemek için bir genel durum değişkenine güvenecek şekilde ayarlardım. Redux, birçok bileşenin birbiriyle konuştuğu bu senaryo için daha iyidir ve bir yorumda bazen kullandığınızdan bahsettiniz. Bu yüzden Redux kullanarak bir cevap çizeceğim.
API çağrılarınızı üst kapsayıcıya taşımanız gerekir Component A
. Torunlarınızın yalnızca API çağrıları tamamlandıktan sonra görüntülenmesini istiyorsanız, bu API çağrılarını torunlarda tutamazsınız. Henüz mevcut olmayan bir bileşenden bir API çağrısı nasıl yapılabilir?
Tüm API çağrıları yapıldıktan sonra, bir grup veri nesnesi içeren bir genel durum değişkenini güncellemek için eylemleri kullanabilirsiniz. Verilerin her alınışında (veya bir hata yakalandığında), veri nesnenizin tamamen doldurulup doldurulmadığını kontrol etmek için bir eylem gönderebilirsiniz. Tamamen dolduğunda, bir loading
değişkeni bileşeninize güncelleyebilir false
ve koşullu olarak Grid
bileşeninizi oluşturabilirsiniz .
Yani mesela:
// Component A
import { acceptData, catchError } from '../actions'
class ComponentA extends React.Component{
componentDidMount () {
fetch('yoururl.com/data')
.then( response => response.json() )
// send your data to the global state data array
.then( data => this.props.acceptData(data, grandChildNumber) )
.catch( error => this.props.catchError(error, grandChildNumber) )
// make all your fetch calls here
}
// Conditionally render your Loading or Grid based on the global state variable 'loading'
render() {
return (
{ this.props.loading && <Loading /> }
{ !this.props.loading && <Grid /> }
)
}
}
const mapStateToProps = state => ({ loading: state.loading })
const mapDispatchToProps = dispatch => ({
acceptData: data => dispatch( acceptData( data, number ) )
catchError: error=> dispatch( catchError( error, number) )
})
// Grid - not much going on here...
render () {
return (
<div className="Grid">
<GrandChild1 number={1} />
<GrandChild2 number={2} />
<GrandChild3 number={3} />
...
// Or render the granchildren from an array with a .map, or something similar
</div>
)
}
// Grandchild
// Conditionally render either an error or your data, depending on what came back from fetch
render () {
return (
{ !this.props.data[this.props.number].error && <Your Content Here /> }
{ this.props.data[this.props.number].error && <Your Error Here /> }
)
}
const mapStateToProps = state => ({ data: state.data })
Redüktörünüz, işlerin henüz tamamlanmaya hazır olup olmadığını söyleyecek küresel devlet nesnesini koruyacaktır:
// reducers.js
const initialState = {
data: [{},{},{},{}...], // 9 empty objects
loading: true
}
const reducers = (state = initialState, action) {
switch(action.type){
case RECIEVE_SOME_DATA:
return {
...state,
data: action.data
}
case RECIEVE_ERROR:
return {
...state,
data: action.data
}
case STOP_LOADING:
return {
...state,
loading: false
}
}
}
Eylemlerinizde:
export const acceptData = (data, number) => {
// First revise your data array to have the new data in the right place
const updatedData = data
updatedData[number] = data
// Now check to see if all your data objects are populated
// and update your loading state:
dispatch( checkAllData() )
return {
type: RECIEVE_SOME_DATA,
data: updatedData,
}
}
// error checking - because you want your stuff to render even if one of your api calls
// catches an error
export const catchError(error, number) {
// First revise your data array to have the error in the right place
const updatedData = data
updatedData[number].error = error
// Now check to see if all your data objects are populated
// and update your loading state:
dispatch( checkAllData() )
return {
type: RECIEVE_ERROR,
data: updatedData,
}
}
export const checkAllData() {
// Check that every data object has something in it
if ( // fancy footwork to check each object in the data array and see if its empty or not
store.getState().data.every( dataSet =>
Object.entries(dataSet).length === 0 && dataSet.constructor === Object ) ) {
return {
type: STOP_LOADING
}
}
}
bir kenara
API çağrılarınızın her bir torun içinde canlı olduğu, ancak tüm API çağrıları tamamlanana kadar tüm torun Izgarasının oluşturulmadığı fikriyle gerçekten evliyseniz, tamamen farklı bir çözüm kullanmanız gerekir. Bu durumda, torunlarınızın çağrılarını yapmak için en baştan yapılması gerekir, ancak display: none
yalnızca global durum değişkeni loading
yanlış olarak işaretlendikten sonra değişen bir css sınıfına sahip olmak gerekir . Bu da yapılabilir, ancak Tepki noktasının yanı sıra.