ReactJs对象文字函数会更新整个状态,而不是预期的状态

时间:2020-05-18 20:08:38

标签: javascript reactjs react-hooks

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

   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 }))

1 个答案:

答案 0 :(得分:2)

我不太确定您期望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 ()
};
相关问题