k16style
k16style

Reputation: 163

React: Functional component render two times the same Div

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.

console output of my render

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

Answers (1)

Daniel Klimuntowski
Daniel Klimuntowski

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

Related Questions