我创建了一个自定义组件(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;
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
有人可以向我解释为什么会这样吗?谢谢。
答案 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();
当我这样做时,一切似乎都正常。
根据上述文章,生产版本也不会产生此类问题。