e.target.classList.{添加||删除 ||切换 } dangerouslySetInnerHtml?
Does e.target.classList.{add || remove || toggle } dangerouslySetInnerHtml?
想问问对 React 有更多经验的人,因为我似乎找不到明确的答案。我知道你不想直接向 DOM 添加文本,这就是为什么 React 让你写 dangerouslySetInnerHtml
来设置它。
但是 classList.{ add || remove || toggle }
呢?使用 classList.add() || .remove()
是否等同于 dangerouslySetInnerHtml
?我也应该担心这样做吗?
例子 - 从组件内部呈现列表的函数 bootstrap css.
问题:在鼠标悬停时将 add/remove .active
设置为 li className
。
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
const RenderList = (array, position = 'text-center') => {
const handleMouseEnter = e => {
e.target.classList.add('active');
};
const handleMouseLeave = e => {
e.target.classList.remove('active');
};
return (
<ul className={`list-group ${position}`}>
{array.map(({ href, key, label, rel, target }) => (
<a key={key} href={href} rel={rel} target={target} fontSize={1.2}>
<li
className={`list-group-item '${key}'`}
data-id={key}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{label}
</li>
</a>
))}
</ul>
);
};
export default RenderList;
问题是 - 我试过将其设置为状态,但它会同时影响所有 li
(我在其他问题中看到过这个问题 - 尽管不是针对功能组件,而是针对类)
这里安全吗?我在浏览器中没有看到任何警告。
如果不安全,有什么替代方案?我尝试使用 li
键中的 data-id
属性,但我无法完全理解单个元素的 useState
...
编辑:有人提出了一个问题作为可能的答案,但它建议为每个列表项创建一个单独的状态实例,这似乎不是一个很好的解决方案。
我想我可能已经找到了解决方法,但我不确定这是否是正确的方法。它仍然操纵 DOM,但使用状态 - 所以 React 可以决定何时执行它:
import React, { useState } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
const RenderList = (array, position = 'text-center') => {
const [isActive, setIsActive] = useState(null);
const [isNotActive, setIsNotActive] = useState(null);
const handleMouseEnter = e => {
setIsActive(e.target.classList.add('active'));
};
const handleMouseLeave = e => {
setIsNotActive(e.target.classList.remove('active'));
};
return (
<ul className={`list-group ${position}`}>
{array.map(({ href, key, label, rel, target }) => (
<a key={key} href={href} rel={rel} target={target} fontSize={1.2}>
<li
className={`list-group-item '${key}'`}
data-id={key}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{label}
</li>
</a>
))}
</ul>
);
};
export default RenderList;
希望得到反馈
手动修改 DOM 是 React 中的反模式
React 是一个数据优先的 UI 库,这意味着数据决定了它应该如何呈现,并且它(几乎)永远不需要读取 DOM。它只写入 DOM,并使用其内部差异算法计算要在 DOM.
中更新的最小块
当我们自己改变 DOM 时,React 不会意识到我们的变化,并且可能会在下一个渲染阶段消除我们的努力。
鼠标悬停时切换样式
尽可能使用 CSS 选择器而不是 JavaScript 选择器来设置组件样式。在这种情况下,它将是一个简单的选择器:
.list-group li:hover {
/* `.active` styles here */
}
如何在每个项目上切换 类?
为了避免管理列表组件中每个单独项目的状态,我会制作一个 Item
组件来管理它自己的状态和事件,让父列表专注于它的实际逻辑。
const { useState } = React;
// Manages its own state and events, making it
// possible to toggle the class here instead.
const Item = ({ to }) => {
const [active, setActive] = useState(false);
return (
<li
className={active? 'active' : ''}
onMouseEnter={() => setActive(true)}
onMouseLeave={() => setActive(false)}
>
<a data-link={to}>{to}</a>
</li>
);
};
// No more class toggling logic needed here.
const List = ({ items }) => (
<ul>
{items.map((itemProps) => <Item {...itemProps} />)}
</ul>
);
ReactDOM.render(
<List items={[{ to: '/home' }, { to: '/foo' }]} />,
document.querySelector('[data-role-react-root]')
);
.active {
background: red;
}
<div data-role-react-root></div>
<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>
想问问对 React 有更多经验的人,因为我似乎找不到明确的答案。我知道你不想直接向 DOM 添加文本,这就是为什么 React 让你写 dangerouslySetInnerHtml
来设置它。
但是 classList.{ add || remove || toggle }
呢?使用 classList.add() || .remove()
是否等同于 dangerouslySetInnerHtml
?我也应该担心这样做吗?
例子 - 从组件内部呈现列表的函数 bootstrap css.
问题:在鼠标悬停时将 add/remove .active
设置为 li className
。
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
const RenderList = (array, position = 'text-center') => {
const handleMouseEnter = e => {
e.target.classList.add('active');
};
const handleMouseLeave = e => {
e.target.classList.remove('active');
};
return (
<ul className={`list-group ${position}`}>
{array.map(({ href, key, label, rel, target }) => (
<a key={key} href={href} rel={rel} target={target} fontSize={1.2}>
<li
className={`list-group-item '${key}'`}
data-id={key}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{label}
</li>
</a>
))}
</ul>
);
};
export default RenderList;
问题是 - 我试过将其设置为状态,但它会同时影响所有 li
(我在其他问题中看到过这个问题 - 尽管不是针对功能组件,而是针对类)
这里安全吗?我在浏览器中没有看到任何警告。
如果不安全,有什么替代方案?我尝试使用 li
键中的 data-id
属性,但我无法完全理解单个元素的 useState
...
编辑:有人提出了一个问题作为可能的答案,但它建议为每个列表项创建一个单独的状态实例,这似乎不是一个很好的解决方案。
我想我可能已经找到了解决方法,但我不确定这是否是正确的方法。它仍然操纵 DOM,但使用状态 - 所以 React 可以决定何时执行它:
import React, { useState } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
const RenderList = (array, position = 'text-center') => {
const [isActive, setIsActive] = useState(null);
const [isNotActive, setIsNotActive] = useState(null);
const handleMouseEnter = e => {
setIsActive(e.target.classList.add('active'));
};
const handleMouseLeave = e => {
setIsNotActive(e.target.classList.remove('active'));
};
return (
<ul className={`list-group ${position}`}>
{array.map(({ href, key, label, rel, target }) => (
<a key={key} href={href} rel={rel} target={target} fontSize={1.2}>
<li
className={`list-group-item '${key}'`}
data-id={key}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{label}
</li>
</a>
))}
</ul>
);
};
export default RenderList;
希望得到反馈
手动修改 DOM 是 React 中的反模式
React 是一个数据优先的 UI 库,这意味着数据决定了它应该如何呈现,并且它(几乎)永远不需要读取 DOM。它只写入 DOM,并使用其内部差异算法计算要在 DOM.
中更新的最小块当我们自己改变 DOM 时,React 不会意识到我们的变化,并且可能会在下一个渲染阶段消除我们的努力。
鼠标悬停时切换样式
尽可能使用 CSS 选择器而不是 JavaScript 选择器来设置组件样式。在这种情况下,它将是一个简单的选择器:
.list-group li:hover {
/* `.active` styles here */
}
如何在每个项目上切换 类?
为了避免管理列表组件中每个单独项目的状态,我会制作一个 Item
组件来管理它自己的状态和事件,让父列表专注于它的实际逻辑。
const { useState } = React;
// Manages its own state and events, making it
// possible to toggle the class here instead.
const Item = ({ to }) => {
const [active, setActive] = useState(false);
return (
<li
className={active? 'active' : ''}
onMouseEnter={() => setActive(true)}
onMouseLeave={() => setActive(false)}
>
<a data-link={to}>{to}</a>
</li>
);
};
// No more class toggling logic needed here.
const List = ({ items }) => (
<ul>
{items.map((itemProps) => <Item {...itemProps} />)}
</ul>
);
ReactDOM.render(
<List items={[{ to: '/home' }, { to: '/foo' }]} />,
document.querySelector('[data-role-react-root]')
);
.active {
background: red;
}
<div data-role-react-root></div>
<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>