从映射数组中单击时更改特定元素的类名,并保持相同的类名,直到在反应中再次单击
Changing classname of a specific element on click from a mapped array an keeping the same classname until clicked again in react
const allTodos = [{id: 1, name: 'whatever user type'}, { }, { }, .... { }] // Defined as an array using setState in other file. Imported in this file as allTodos using props.
export const Todos = (props) => {
const [index, setIndex] = useState(0)
props.allTodos.map((prev) => {
return (
<div id="item_container">
<button type='button' className = `check_button ${prev.id === index ? 'checked' : 'not_checked'}`
onClick = {() => setIndex(prev.id)}>
<img src = {check} alt="" id = "check_img"></img>
</button>
<li id="li_item">{prev.name}</li>
</div>
)}
}
说明:在这里,我使用 useState
设置了一个 const index
,它将把它的值更改为所单击元素的 ID,以更改该元素的 className
元素.
问题:现在,我成功地做到了,但每次我单击其他元素时,className
都会添加到该元素,但会从添加它的前一个元素中删除。现在我想以某种方式将 className
保留到我单击的每个元素,直到我再次单击它们以更改它们的 className
。顺便说一句,我想要更改的样式是 button/element.
的 background
您需要能够跟踪检查的每个 索引——为此您需要一个数组(或一个用于进行位计算的数字)。有状态的 index
号码没有包含足够的信息。
const allTodos = [{ id: 1, name: 'whatever user type' }, { id: 2, name: 'foo' }];
const Todos = ({ allTodos }) => {
const [todos, setTodos] = React.useState(() => allTodos.map(todo => ({ ...todo, checked: false })));
const handleClick = (i) => () => {
setTodos(todos.map((todo, j) => j !== i ? todo : ({ ...todo, checked: !todo.checked })))
};
return todos.map(({ id, name, checked }, i) => (
<div id="item_container">
<button
type='button'
className={`check_button ${checked ? 'checked' : 'not_checked'}`}
onClick={handleClick(i)}
>
<img alt="" id="check_img"></img>
</button>
<div>{name}</div>
</div >
))
}
ReactDOM.render(<Todos allTodos={allTodos} />, document.querySelector('.react'));
.checked {
background-color: green;
}
.not_checked {
background-color: yellow;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>
您还需要:
- 当不使用纯
'
"
引号时,在 prop 周围使用 {}
分隔符
<li>
s 应该只是 children 个 <ul>
s
- 重复的 ID 无效 HTML
- 您需要 return 来自
Todos
组件的映射 JSX
- 您在
allTodos.map
末尾缺少一个 )
您应该使用数组来保存点击并在再次点击时从数组中删除 id。
const [idList, setIdList] = useState([])
const handleClick=(id, checked) => {
if(checked){
setIdList.filter(item => item !== id)
} else {
setIdList([...idList, id])
}
}
props.allTodos.map((prev) => {
const checked = idList.includes(prev.id)
...
className ={`check_button ${checked ? 'checked' : 'not_checked'}`}
onClick = {() => handleClick(prev.id, checked)
...
const allTodos = [{id: 1, name: 'whatever user type'}, { }, { }, .... { }] // Defined as an array using setState in other file. Imported in this file as allTodos using props.
export const Todos = (props) => {
const [index, setIndex] = useState(0)
props.allTodos.map((prev) => {
return (
<div id="item_container">
<button type='button' className = `check_button ${prev.id === index ? 'checked' : 'not_checked'}`
onClick = {() => setIndex(prev.id)}>
<img src = {check} alt="" id = "check_img"></img>
</button>
<li id="li_item">{prev.name}</li>
</div>
)}
}
说明:在这里,我使用 useState
设置了一个 const index
,它将把它的值更改为所单击元素的 ID,以更改该元素的 className
元素.
问题:现在,我成功地做到了,但每次我单击其他元素时,className
都会添加到该元素,但会从添加它的前一个元素中删除。现在我想以某种方式将 className
保留到我单击的每个元素,直到我再次单击它们以更改它们的 className
。顺便说一句,我想要更改的样式是 button/element.
background
您需要能够跟踪检查的每个 索引——为此您需要一个数组(或一个用于进行位计算的数字)。有状态的 index
号码没有包含足够的信息。
const allTodos = [{ id: 1, name: 'whatever user type' }, { id: 2, name: 'foo' }];
const Todos = ({ allTodos }) => {
const [todos, setTodos] = React.useState(() => allTodos.map(todo => ({ ...todo, checked: false })));
const handleClick = (i) => () => {
setTodos(todos.map((todo, j) => j !== i ? todo : ({ ...todo, checked: !todo.checked })))
};
return todos.map(({ id, name, checked }, i) => (
<div id="item_container">
<button
type='button'
className={`check_button ${checked ? 'checked' : 'not_checked'}`}
onClick={handleClick(i)}
>
<img alt="" id="check_img"></img>
</button>
<div>{name}</div>
</div >
))
}
ReactDOM.render(<Todos allTodos={allTodos} />, document.querySelector('.react'));
.checked {
background-color: green;
}
.not_checked {
background-color: yellow;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>
您还需要:
- 当不使用纯
'
"
引号时,在 prop 周围使用 <li>
s 应该只是 children 个<ul>
s- 重复的 ID 无效 HTML
- 您需要 return 来自
Todos
组件的映射 JSX - 您在
allTodos.map
末尾缺少一个
{}
分隔符
)
您应该使用数组来保存点击并在再次点击时从数组中删除 id。
const [idList, setIdList] = useState([])
const handleClick=(id, checked) => {
if(checked){
setIdList.filter(item => item !== id)
} else {
setIdList([...idList, id])
}
}
props.allTodos.map((prev) => {
const checked = idList.includes(prev.id)
...
className ={`check_button ${checked ? 'checked' : 'not_checked'}`}
onClick = {() => handleClick(prev.id, checked)
...