【问题标题】:Why onClick handler not changing className of icon tag?为什么 onClick 处理程序不更改图标标签的类名?
【发布时间】:2021-07-27 17:57:16
【问题描述】:

每当我单击具有与其链接的 onClick 处理程序的方形图标时,它都不会更改该图标的类名。

如果 box.isChecked === true 在图标标签内,那么我想显示“far fa-check-square icon”的类名
但是如果 box.isChecked === false 那么我想显示“far fa-square icon”的类名。但它不起作用。

应用js文件:

import React , {useState} from 'react'
const data = [
{
    id:0,
    para:"This is Box One",
    isChecked:false
},
{
    id:1,
    para:"This is Box Two",
    isChecked:false
},
{
    id:2,
    para:"This is Box Three",
    isChecked:false
},
{
    id:3,
    para:"This is Box Four",
    isChecked:false
}];


const App = () => {
let [list,setList] = useState(data);

const checked = (id) => {
    for(let i = 0;i < list.length;i++){
        if(i === id){
            if(list[i].isChecked === false){
                list[i].isChecked = true;
                break;
            }else{
                list[i].isChecked = false;
                break;
            }
        }
    }
    let newList = list;
    console.log(newList);
    setList(newList);
}

return(
    <>
        {list.map((box) => {
            return (
                <div className="box" key={box.id}>
                    <i className={box.isChecked === true ? "far fa-check-square icon":"far fa-square icon"} onClick={() => checked(box.id)}> </i>
                    <p className="para"> {box.para} </p>
                </div>
            )
        })}
    </>
)}
export default App;

索引js文件:

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import './index.css'
ReactDOM.render(<App />,document.getElementById("root"));

索引 css 文件:

*{
margin:0px;
padding:0px;
box-sizing:border-box;
}
.box{
width:250px;
padding:15px;
margin:0px 0px 15px 0px;
background-color:rgb(81, 162, 255);
}
.icon{
font-size:25px;
cursor:pointer;
color:white;
margin:0px 0px 5px 0px;
}
.para{
font-size:20px;
font-family:arial;
color:white;
}

【问题讨论】:

  • console.log 是否显示更改?
  • 是的,console.log 显示了变化,但 className 仍然没有变化。

标签: javascript html reactjs typescript react-native


【解决方案1】:

在此代码块中,您不会更改对数组的引用,只是更改值。 setState 不会触发重新渲染,除非值引用发生变化。

const checked = (id) => {
    for(let i = 0;i < list.length;i++){
        if(i === id){
            if(list[i].isChecked === false){
                list[i].isChecked = true;
                break;
            }else{
                list[i].isChecked = false;
                break;
            }
        }
    }
    let newList = list; // <-- you are not creating a new array here.
    console.log(newList);
    setList(newList);
}

要解决此问题,您可以使用更新后的值克隆数组。

setList([...list]);

【讨论】:

    【解决方案2】:

    问题在于 React 通过执行浅对象相等性检查来检查 props 和 state 的变化。如果你将状态设置为相同的初始对象/数组,React 不会做任何更新。

    所以你应该这样做

    let newList = [...list]; 
    
        setList(newList);
    

    【讨论】:

    • 效果很好,非常感谢兄弟。
    【解决方案3】:

    您应该始终避免改变您的状态,您的问题是您传递的是相同的引用而不是您的数组的克隆,因此您的状态根本不会在内部更新。

    import React , {useState} from 'react'
    const data = [
    {
        id:0,
        para:"This is Box One",
        isChecked:false
    },
    {
        id:1,
        para:"This is Box Two",
        isChecked:false
    },
    {
        id:2,
        para:"This is Box Three",
        isChecked:false
    },
    {
        id:3,
        para:"This is Box Four",
        isChecked:false
    }];
    
    
    const App = () => {
    let [list,setList] = useState(data);
    
    const updateList = (id) => {
        setList((prevList) => {
            return prevList.map((box) => {
               if(box.id === id){
                 if(!box.isChecked){
                   box.isChecked = true;
                 } else {
                   box.isChecked = false;
                 }
               }
             })
        });
    }
    
    return(
        <>
            {list.map((box) => {
                return (
                    <div className="box" key={box.id}>
                        <i className={box.isChecked === true ? "far fa-check-square icon":"far fa-square icon"} onClick={() => updateList(box.id)}> </i>
                        <p className="para"> {box.para} </p>
                    </div>
                )
            })}
        </>
    )}
    export default App;
    

    【讨论】:

      猜你喜欢
      • 2012-01-28
      • 2021-09-16
      • 1970-01-01
      • 2012-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多