首页 > 解决方案 > 为什么我的主导航栏被渲染了两次?

问题描述

我创建了一个自定义组件(MainNavbar)来渲染我的导航栏,但出于某种奇怪的原因,我似乎无法理解为什么它会被渲染两次。

这是来自组件的控制台日志的屏幕截图。

在此处输入图像描述

MainNavbar下面是与组件交互的主要部分的代码

MainNavbar.jsx

import React from 'react';
import { useHistory } from 'react-router';
import { useDispatch, useSelector } from 'react-redux';
import { Link, NavLink } from 'react-router-dom';
import { Container, Nav, Navbar, NavDropdown } from 'react-bootstrap';
import _ from 'lodash';
import { logout, selectUser } from '../store/modules/auth';

const MainNavbar = () => {
    console.log('start');
    const history = useHistory();
    const dispatch = useDispatch();
    const user = useSelector(selectUser);
    console.log(user, 'middle');

    return (
        <Navbar bg="light" variant="light">
            <Container>
                <Link className="navbar-brand" to="/">
                    App
                </Link>
                <Nav className="ml-auto">
                    {user && (
                        <NavDropdown
                            title={_.startCase(user.username)}
                            id="nav-dropdown"
                        >
                            <NavDropdown.Item
                                href="#"
                                onClick={(e) => {
                                    e.preventDefault();

                                    dispatch(logout());

                                    history.push('/login');
                                }}
                            >
                                Logout
                            </NavDropdown.Item>
                        </NavDropdown>
                    )}
                    {!user && (
                        <NavLink className="nav-link" to="/login" exact>
                            Login {console.log('end')}
                        </NavLink>
                    )}
                </Nav>
            </Container>
        </Navbar>
    );
};

export default MainNavbar;

auth.js

import { createSlice } from '@reduxjs/toolkit';
import { createSelector } from 'reselect';
import http from '../../services/http';

const baseURL = '/auth';

const slice = createSlice({
    name: 'auth',
    initialState: {
        user: null,
    },
    reducers: {
        SET_USER: (auth, action) => ({
            user: action.payload,
        }),
    },
});

export const selectUser = createSelector(
    (state) => state.auth.user,
    (user) => user
);

const { SET_USER } = slice.actions;

export const login = (credentials) => async (dispatch) => {
    ...
};

export const authenticate = () => async (dispatch, getState) => {
    ...
};

export const logout = () => async (dispatch) => {
    ...
};

export default slice.reducer;

应用程序.js

import React from 'react';
import { Container } from 'react-bootstrap';
import { ToastContainer } from 'react-toastify';
import Routes from './router';
import MainNavbar from './components/MainNavbar';

function App() {
    return (
        <>
            <ToastContainer position="top-center" autoClose={5000} />
            <MainNavbar />
            <Container id="wrapper">
                <Routes />
            </Container>
        </>
    );
}

export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';
import store from './store';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
    <Provider store={store}>
        <BrowserRouter>
            <React.StrictMode>
                <App />
            </React.StrictMode>
        </BrowserRouter>
    </Provider>,
    document.getElementById('root')
);

serviceWorker.unregister();

我的反应项目结构看起来像这样

.
├── package.json
├── package-lock.json
├── public
│   ...
├── README.md
└── src
    ├── App.js
    ├── App.test.js
    ├── components
    │   ├── admin
    │   │   └── ...
    │   ├── common
    │   │   └── ...
    │   ├── Index.jsx
    │   ├── Login.jsx
    │   ├── MainNavbar.jsx
    │   └── NotFound.jsx
    ├── index.js
    ├── router
    │   └── ...
    ├── services
    │   └── http.js
    └── store
        ├── index.js
        ├── middleware
        ├── modules
        │   └── auth.js
        └── reducer.js

有人可以向我解释为什么会这样吗?谢谢你。

标签: javascriptreactjsrendering

解决方案


我刚刚在 react Github 页面上找到了这篇文章和这个问题,这在一定程度上解释了它发生的原因,并且根据反应团队的说法,这是故意的。

所以我所做的就是改变我src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';
import store from './store';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
    <Provider store={store}>
        <BrowserRouter>
            {/* <React.StrictMode> */}
            <App />
            {/* </React.StrictMode> */}
        </BrowserRouter>
    </Provider>,
    document.getElementById('root')
);

serviceWorker.unregister();

当我这样做时,一切似乎都运行良好。

同样根据上述文章,生产版本不会产生此类问题。


推荐阅读