为什么我的mainnavbar被渲染两次?

时间:2020-05-14 07:24:55

标签: javascript reactjs rendering reduxjs-toolkit

我创建了一个自定义组件(MainNavbar)来渲染导航栏,但由于某些奇怪的原因,我似乎无法将其渲染两次的原因笼罩在脑海中。

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

enter image description here

下面是与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;

App.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();

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

.
├── 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

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

1 个答案:

答案 0 :(得分:0)

我刚刚在React Github页面上找到了这个article和这个issue,这在一定程度上解释了为什么会发生这种情况,而据React团队说,这是有意的。

所以我要做的就是将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();

当我这样做时,一切似乎都正常。

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