首页 > 解决方案 > ReactJs 对象文字函数更新整个状态而不是预期

问题描述

我有一个简单的字体真棒星评级。只有被点击的星星应该变成橙色,其余的不应该。橙色星的类别取决于状态。下面的代码

   import React, {useState} from 'react';
   import './rating.css';

function Rating() {

  const [state, setState] = useState({first:false, second:false, third:false, fourth:false, 
                                     fifth:false});

    const rate = (index) => {
        console.log(index)
        return{
            '1': setState(prevState=>({...prevState, first: !state.first })),
            '2': setState(prevState=>({...prevState, second: !state.second })),
            '3': setState(prevState=>({...prevState, third: !state.third })),
            '4': setState(prevState=>({...prevState, fourth: !state.fourth })),
            '5': setState(prevState=>({...prevState, fifth: !state.fifth }))
        }[index]
    };

    return (
        <div className="rating">
            <span className={`fa fa-star ${state.first ? "checked" : ""}`} onClick={()=>rate('1')}></span>
            <span className={`fa fa-star ${state.second ? "checked" : ""}`} onClick={()=>rate('2')}></span>
            <span className={`fa fa-star ${state.third ? "checked" : ""}`} onClick={()=>rate('3')}></span>
            <span className={`fa fa-star ${state.fourth ? "checked" : ""}`} onClick={()=>rate('4')}></span>
            <span className={`fa fa-star ${state.fifth ? "checked" : ""}`} onClick={()=>rate('5')}></span>
        </div>
    )
}

export default Rating;

问题是当我点击一颗星星时,所有的星星都会变黄。预计速率函数中的索引将决定切换哪个星的状态。控制台记录...索引在速率函数中正确。我试过没有 prevState/callback 和下面的匿名函数。没有任何帮助。这里出了什么问题?

'1': ()=>setState(prevState=>({...prevState, first: !state.first }))

标签: javascriptreactjsreact-hooks

解决方案


我不太确定您希望该rate函数做什么。似乎您已经创建了一个对象,该对象应该为每个索引都有一个方法,然后您试图通过[index]? 这种方式不仅过于复杂,而且设置也不正确。您正在调用setState每个方法,而不是分配函数(如() => setState(...))。

我建议您根本不要使用此“索引”系统,而只需传递您要更新的值:

const rate = (name) => {
  setState({ ...state, [name]: !state[name] });
};

...

// Example usage:
<span className={`fa fa-star ${state.first ? "checked" : ""}`} onClick={()=>rate('first')}></span>

如果您打算使用对象样式,请尝试以下操作(未经测试):

const rate = (index) => {
  let actions = {
    '1': () => setState(prevState=>({...prevState, first: !prevState.first })),
    '2': () => setState(prevState=>({...prevState, second: !prevState.second })),
    '3': () => setState(prevState=>({...prevState, third: !prevState.third })),
    '4': () => setState(prevState=>({...prevState, fourth: !prevState.fourth })),
    '5': () => setState(prevState=>({...prevState, fifth: !prevState.fifth }))
  };

  actions[index]() // <-- call it with ()
};

推荐阅读