#javascript #reactjs
#javascript #reactjs
Вопрос:
У меня есть отображение типа списка и сетки. Как мне переключаться между ними в React. Я хочу переключаться между классами jsGridView и jsListView.
Это ванильный js для переключения классов
const listView = document.querySelector('.list-view');
const gridView = document.querySelector('.grid-view');
const projectsList = document.querySelector('.project-boxes');
listView.addEventListener('click', () => {
gridView.classList.remove('active');
listView.classList.add('active');
projectsList.classList.remove('jsGridView');
projectsList.classList.add('jsListView');
});
gridView.addEventListener('click', () => {
gridView.classList.add('active');
listView.classList.remove('active');
projectsList.classList.remove('jsListView');
projectsList.classList.add('jsGridView');
});
** это мой файл react, в котором у меня есть элементы отображения и кнопки для переключения. как мне реализовать прослушиватели событий переключения в моем файле react**
Как мне переключаться между двумя классами — jsGridVew и jsListView
const [isActive, setIsActive] = useState(false)
const listToggle = () => {
setIsActive(!isActive)
}
<button key={isActive} className="view-btn list-view" title="List View" onClick={listToggle}>
<i className="fal fa-list-ul fa-2x"></i>
</button>
<button className="view-btn grid-view active" title="Grid View">
<i className="fal fa-th-large fa-2x"></i>
</button>
<div className="project-boxes jsGridView">
{!loading amp;amp; records.length === 0 ? (<h4 style={{ margin: '20px' }} className='center'>No
records, sorry</h4>) : records.map((record, key) => (
<RecordItem key={key} record={record} isFilter={isFilter} filterByWhat={filterByWhat} />
))}
</div>
РЕДАКТИРОВАТЬ: > Я также хочу добавить «активный класс» для каждой кнопки при нажатии. Я пробовал что-то, но это не работает
Ответ №1:
Я предполагаю, что в этом div вы хотите переключаться между jsGridView
и jsListView
<div className="project-boxes jsGridView">
Так почему бы не использовать переменную состояния для хранения имени класса? Затем используйте onClick
четный, чтобы установить его.
const [cName, setClassName] = useState('jsGridView');
return (
<Fragment>
<button className="view-btn list-view" title="List View" onClick={() => setClassName('jsListView')}>
List View
</button>
<button className="view-btn list-view" title="Grid View" onClick={() => setClassName('jsGridView')}>
Grid View
</button>
<div className={"project-boxes " cName}>
{!loading amp;amp; records.length === 0 ? (<h4 style={{ margin: '20px' }} className='center'>No
records, sorry</h4>) : records.map((record, key) => (
<RecordItem key={key} record={record} isFilter={isFilter} filterByWhat={filterByWhat} />
))}
</div>
</Fragment>
)
Итак, здесь вы устанавливаете для своего класса значение jsGridView
initially, чтобы он отображался в виде сетки по умолчанию. Но у вас также есть 2 кнопки, которые могут переключать его между сеткой и списком.
Вы также можете добавить активный класс к кнопке, если хотите.
<button className={"view-btn list-view" (cName === 'jsListView' ? ' active_btn':'')} title="List View" onClick={() => setClassName('jsListView')}>
List View
</button>
<button className={"view-btn list-view" (cName === 'jsGridView' ? ' active_btn':'')} title="Grid View" onClick={() => setClassName('jsGridView')}>
Grid View
</button>
Ответ №2:
Если один класс включен, а другой выключен, вы можете сделать
function toggleClass(elem) {
const classList = elem.classList;
classList.toggle('class1');
classList.toggle('class2');
}
Теперь статус включения / выключения двух классов меняется на противоположный
Кроме того, в вашем файле Styles / CSS вы можете добавить:не для одного класса, а затем не нужно использовать другой класс, например
#elem.class1 {
color: ...;
font-size: ...;
}
#elem.class2, #elem:not(.class1) {
color: ...;
font-size: ...;
}
Так что :not(.class1) имеет те же эффекты стилизации, что и добавление class2
Ответ №3:
В React необычно смешивать «ванильный» императивный JS и реагировать подобным образом. React предоставляет простое решение для переключения отображаемых элементов, которое я бы посоветовал вам использовать вместо этого.
В качестве примера возьмем следующее:
// list-view.jsx
const ListView = ({ items=[] }) => {
const itemsElements = items.map(item => {
return (<li>{item}</li>)
});
return (<ul>{itemsElements}</ul>)
}
// grid-view.jsx
const GridView = ({ items=[] }) => {
const itemsElements = items.map(item => {
return (<span>{item} </span>)
});
return (<div>{itemsElements}</div>)
}
// list-grid-view.jsx
const ListGridView = ({ items=[] }) => {
const [listView, setListView] = React.useState(true);
// this fn toggles the listView variable
const toggleListView = React.useCallback(() => {
setListView(!listView);
}, [listView, setListView]);
return (
<div>
<button onClick={toggleListView} >Toggle!</button>
{listView ? <ListView items={items} /> : <GridView items={items} />}
</div>
);
}
const items = ['Hello', 'World', '!'];
const element = <ListGridView items={items} />
ReactDOM.render(element, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>