React component rendering twice

Asked

Viewed 259 times

0

Guys I’m having a problem where my components are rendered 2/3 times and I’m suspicious of an implementation, but I’m not sure if it’s her fault. The implementation is as follows, I have a LayoutContext responsible for controlling the props that I pass to my layout as follows:

class App extends Component {
render() {
    return (
        <AuthProvider>
            <LayoutProvider>
                <Provider {...store}>
                    <Routes></Routes>
                </Provider>
            </LayoutProvider>
        </AuthProvider>
    );
}

}

This is where I spend my props consuming mine LayoutContext:

  render() {
    const Layout = this.getLayout();
    // rendering the router with layout
    return (
        <BrowserRouter>
        <LayoutContext.Consumer>
        {value => {
            return(
  
            <Layout 
                {...this.props}
                hideSearch={value.hideSearch}
                pageTitle={value.pageTitle}
                topBarModule={value.topBarModule}
                leftSideBarClass={value.leftSideBarClass}
                headChildren={value.headChildren}
            >
                <Switch>
                    {routes.map((route, index) => {
                        return (
                            !route.children && (
                                <route.route
                                    key={index}
                                    path={route.path}
                                    roles={route.roles}
                                    exact={route.exact}
                                    component={route.component}></route.route>
                            )
                        );
                    })}
                </Switch>
            </Layout>
                  )}}
                  </LayoutContext.Consumer>
        </BrowserRouter>
    );
}
}

And then to change the layout I do this (I think the error is here), inside the ComponentDidMount of each component I want to make the layout change I change the props of my LayoutContext:

    static contextType = LayoutContext;

componentDidMount() {
    console.log("passou aqui")
    const { financialBasics, setHeadChildren, setPageTitle } = this.context
    setPageTitle("Clientes e Fornecedores > Exibir Todos")
    setHeadChildren()
    financialBasics()
}

the console.log of ComponentDidMount is fired twice and if I take the LayoutContext he’s only fired once, so I suspect that’s it

#EDIT - 1

const Routes = (props) => {


const layoutContext = useContext(LayoutContext)

const layoutMemo = useMemo(() => {
    return layoutContext
}, layoutContext)

const propsMemo = useMemo(() => {
    return props
}, props)


// returns the layout
const getLayout = () => {

    if (layoutContext.isModule) return AuthLayout;

    let layoutCls = VerticalLayout;

    switch (props.layout.layoutType) {
        case layoutConstants.LAYOUT_HORIZONTAL:
            layoutCls = HorizontalLayout;
            break;
        case layoutConstants.LAYOUT_DETACHED:
            layoutCls = DetachedLayout;
            break;
        default:
            layoutCls = VerticalLayout;
            break;
    }
    return layoutCls;
};



const Layout = getLayout();

return (
    <BrowserRouter>
        <Layout
            {...propsMemo}
            {...layoutMemo}
        >
            <Switch>
                {routes.map((route, index) => {
                    return (
                        !route.children && (
                            <route.route
                                key={index}
                                path={route.path}
                                roles={route.roles}
                                exact={route.exact}
                                component={route.component}></route.route>
                        )
                    );
                })}
            </Switch>
        </Layout>
    </BrowserRouter>
);
}

const mapStateToProps = state => {
return {
    layout: state.Layout,
    user: state.Auth.user,
   };
};

export default connect(mapStateToProps, null)(Routes)
  • 1

    With each change of property or props. the tree is updated. You’re right that’s what really happens. As the elements share the same properties others who have need to know this change if they are not outdated. This is not problem basically talking is the same working. Study memo that can help you improve it

  • 1

    Also take a look at your index.js. React in Strictmode, render 2 times to check for possible errors, then after build this does not happen.

  • @novic thanks, so the implementation is not wrong, but could be improved with memo? This memo would prevent this double rendering?

  • @Kakiz how do I know if I’m using Strictmode?

  • yes can ... you have to know how to use memo https://pt-br.reactjs.org/docs/hooks-reference.html#usememo e https://pt-br.reactjs.org/docs/react-api.html#reactmemo

  • @Guilhermeprado in your index.js file, see if your <App/> is involved by <React.StrictMode>

  • @novic I studied on the memo and really it seems very advantageous thank you! Even not solving my problem was cool to see how it works, does it make sense the refactoring I did using memo? It’s in the "#EDIT 1" of my post. I was wondering if I should use the memo at this stage or within Layoutcontext. Thanks!

  • Honestly I have no way to test

Show 3 more comments
No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.