Reputation: 163
I'm trying to make a web application using React and Redux. A reducer call an api of my backend and this api returns a Json of categories. But I realized when I call this reducer and the state from a component functional for someone reason the div that contains the state was rendered two times. In the first render the array of my json of categories doesn't exist but in the second render the array of my json of categories exists.
This is my component code:
import React, { useRef, useEffect} from 'react'
import { NavLink, Link } from 'react-router-dom'
import { connect } from 'react-redux'
import PrivateMenu from '../Molecules/PrivateMenu'
import PublicMenu from '../Molecules/PublicMenu'
<div className="header-list-categories-container">
<div className="sub-list-container">
<label htmlFor="">{console.log('')}</label>
<label htmlFor="">{console.log('the div X starts')}</label>
<label htmlFor="">{console.log(thecategories)}</label>
<label htmlFor="">{thecategories?console.log('the array exists'):console.log('the array does not exists')}</label>
<label htmlFor="">{console.log('the div X ends')}</label>
</div>
</div>
const mapStateToProps = state =>(
{
thecategories : state.categoriaReducer.categories
}
)
export default connect(mapStateToProps)(Header)
This is my app.jsx calls to my component functional Header:
import React from 'react';
import '../App.css';
import { BrowserRouter as Router, Route, Switch} from 'react-router-dom';
import Header from './Organisms/Header'
import Home from './pages/Home'
const App = ()=>(
<Router>
<Header />
<Switch>
<Route path="/" exact component={Home} />
</Switch>
</Router>
)
export default App;
and this is my index.js calls app.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App';
import store from './redux/store'
import { Provider } from 'react-redux'
import { getallcategories} from './redux/actionCreators'
store.dispatch(getallcategories())
ReactDOM.render(
<Provider store ={store}>
<App />
</Provider>
,document.getElementById('root'));
Upvotes: 0
Views: 210
Reputation: 78
It seems like what you're describing is a normal behavior when fetching data asynchronously from backend - a component renders without the data during mount and then, when its props change (react-redux
injects them), React rerenders it, as it should, with the actual data.
The general convention is to display some information to a user when there is no data available yet - either a load spinner or a custom "empty list" component.
Example:
// your Header component would look like so
// I've defaulted the 'thecategories' prop to an empty array for ease of use
const Header = ({ thecategories = []}) => {
if (thecategories.length === 0) {
return (<div>No data available.</div>);
} else {
return (
<div className="header-list-categories-container">
<div className="sub-list-container">
<label htmlFor="">{console.log('')}</label>
<label htmlFor="">{console.log('the div X starts')}</label>
<label htmlFor="">{console.log(thecategories)}</label>
<label htmlFor="">{console.log('the array always exists at this point ;)')}</label>
<label htmlFor="">{console.log('the div X ends')}</label>
</div>
</div>)
};
);
Upvotes: 2