У меня следующая проблема: у меня есть компонент, который отображает в нем другие компоненты. Один из этих компонентов получает переменные состояния моего родительского компонента в качестве параметра и активно их использует, но они не перерисовываются при изменении состояния родительского компонента. Другая проблема, с которой я столкнулся, заключается в том, что у меня есть дополнительный элемент в моем списке, который активируется, когда у пользователя есть специальный идентификатор роли. Изменение состояния работает полностью нормально, но в этой ситуации дополнительный элемент становится видимым только после того, как я изменил параметр пути своего URL-адреса.
родительский компонент:
import React, { useEffect, useState } from 'react';
import {Row, Col} from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
import '../../App.css';
import ProfileSettings from './profileSettings';
import SettingsChooser from './settingsChooser';
// import SettingRoutings from '../settingRoutings';
import {BrowserRouter as Router, useHistory, useLocation, useParams} from 'react-router-dom';
// import Routings from '../Routings.js';
import UserRequests from './userRequests';
import useAuth from '../../API/useAuthentification';
import { CONTROLLERS, useBackend } from '../../hooks/useBackend';
function UserSettings({user}) {
const {title: path} = useParams();
const [acst, setAcst] = useState(localStorage.accessToken);
const [rft, setRft] = useState(localStorage.refreshToken);
const history = useHistory();
const [items, setItems] = useState(['Profile', 'Requests','Log Out', 'Delete Account']);
const [authError, setAuthError] = useState(false);
const [userValues, authentificate] = useBackend(authError, setAuthError, user);
const [component, setComponent] = useState(<></>);
const [defaultItem, setDefaultItem] = useState(0);
useEffect(() => {
console.log('render');
authentificate(CONTROLLERS.USERS.getUserByAccessToken());
}, [acst, rft]);
window.addEventListener('storage', () => localStorage.accessToken !== acst ? setAcst(localStorage.accessToken) : '');
window.addEventListener('storage', () => localStorage.refreshToken !== rft ? setRft(localStorage.refreshToken) : '');
useEffect(() => {
if(userValues?.roleID === 1) {
items.splice(0, 0, 'Admin Panel');
setItems(items);
}
console.log(items);
}, [userValues]);
useEffect(() => {
// if(path==='logout') setDefaultItem(2);
// else if(path==='deleteAccount') setDefaultItem(3);
// else if(path==='requests') setDefaultItem(1);
}, [])
const clearTokens = () => {
localStorage.accessToken = undefined;
localStorage.refreshToken = undefined;
}
useEffect(() => {
console.log(path);
if(path ==='logout' && !authError) {
setDefaultItem(2);
clearTokens();
}
else if(path === 'deleteaccount') {
setDefaultItem(3);
if(userValues?.userID && !authError) {
authentificate(CONTROLLERS.USERS.delete(userValues.userID));
}
clearTokens();
history.push('/movies/pages/1');
}
else if(path==='requests') {
setDefaultItem(1);
setComponent(<UserRequests user={userValues} setAuthError={setAuthError} authError={authError}/>);
} else {
setComponent(<ProfileSettings user={userValues} setAuthError={setAuthError} authError={authError}/>);
}
}, [path]);
useEffect(() => {
console.log(defaultItem);
}, [defaultItem])
return (
<div >
<Row className="">
<Col className="formsettings2" md={ {span: 3, offset: 1}}>
<SettingsChooser items={items} headline={'Your Details'} defaultpath='userSettings' defaultactive={defaultItem} />
</Col>
<Col className="ml-5 formsettings2"md={ {span: 6}}>
{authError ? <p>No Access, please Login first</p> : component}
</Col>
</Row>
</div>
);
}
export default UserSettings;
Дочерний компонент (settingsChooser):
import React, {useEffect, useState} from 'react';
import {Card, Form, Button, Nav, Col} from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
import { LinkContainer } from 'react-router-bootstrap';
import '../../App.css'
function SettingsChooser({items, headline, defaultpath, defaultactive}) {
const [selected, setSelected] = useState(defaultactive);
const handleClick = (e, key) => {
setSelected(key);
}
useEffect(() => console.log("rerender"), [items, defaultactive]);
useEffect(() => {
setSelected(defaultactive);
}, [])
return(
<>
<Card className="shadow-sm">
<Card.Header className="bg-white h6 ">{headline}</Card.Header>
{items.map((item, idx) =>{
return(
<LinkContainer to={`/${defaultpath}/${(item.replace(/\s/g,'').toLowerCase())}`}><Nav.Link onClick={(e) => handleClick(this, idx)} className={'text-decoration-none text-secondary item-text ' + (selected === idx? 'active-item' : 'item')}>{item}</Nav.Link></LinkContainer>
);
})}
</Card>
</>
);
}
export default SettingsChooser;