【问题标题】:react state not updating on input change反应状态不更新输入更改
【发布时间】:2021-11-27 10:36:08
【问题描述】:

我在 useState 挂钩中有一个对象数组,我用它来渲染输入元素。 输入元素更改时状态不会更新。

这是我的代码。

ProceduralResponseAnswerCreate Component

const ProceduralResponseAnswerCreate = () => {
    const [proceduralAnswers, setProceduralAnswers] = useState([{ "value": "One" }, { "value": "two" }])
    return <>
        <ol>
            {proceduralAnswers.map((answer, answer_index) => <input key={answer_index} style={inputStyle} onChange={(event) => updateAnswerValue({ event, setProceduralAnswers, answer_index })} value={answer.value} />)}
        </ol>
    </>
}

export default ProceduralResponseAnswerCreate

updateAnswerValue函数

export const updateAnswerValue = ({ event, setProceduralAnswers, answer_index }) => {

    setProceduralAnswers(state => {
        var newState = state;
        var currentAnswer = newState.filter((state_1, index) => index === answer_index)[0]
        currentAnswer.value = event.target.value
        return newState
    })
}

【问题讨论】:

  • 尝试将 updateAnswerValue 函数移动到您的组件中,您不需要导入它并将 setState 函数作为道具发送给它,或者在您的组件中创建一个使用 setProceduralAnswers 状态设置器的不同函数, 并将其作为回调函数 prop 传递。
  • 我创建了这个示例,希望对您有所帮助 - codesandbox.io/s/affectionate-silence-rbbkm?file=/src/…

标签: reactjs state use-state


【解决方案1】:

首先,如果您只想查找一个项目,请使用 [].find 而不是 filter

var newState = state; 不会给你一个新的副本,改变 newState,你也会改变状态,你需要做var newState = [...state];(警告:这只是一个浅拷贝)。

您似乎认为currentAnswer 在某种程度上与newState 共享引用,但事实并非如此。每当您运行 mapfindfilterreduce 时,您都会获得数组的新副本,因此两者之间不会有链接。

这里最好只映射状态

export const updateAnswerValue = ({
    event,
    setProceduralAnswers,
    answer_index
}) => {
    setProceduralAnswers((state) => state.map((state_1, index) => {
        if (index === answer_index) {
            return {
                ...state_1,
                value: event.target.value
            }
        }

        return state_1;
    }));
};

【讨论】:

    【解决方案2】:

    我认为它不起作用,因为下一个状态与前一个状态具有相同的引用,您只需更改一个元素的值。如果引用发生变化,useState 挂钩将触发重新渲染。所以你的回调必须是这样的。

    setProceduralAnswers(state => {
        let newState = state;
        let currentAnswer = newState.filter((state_1, index) => index === answer_index)[0]
        currentAnswer.value = event.target.value
        return [...newState]
    })
    

    【讨论】:

      【解决方案3】:

      您返回的是 newState 而不是 currentAnswer。

      【讨论】:

        【解决方案4】:

        试试这个

        export const updateAnswerValue = ({ event, setProceduralAnswers, answer_index }) => {
            
                setProceduralAnswers(state => {
                    var newState = state;
                    newState[answer_index].value = event.target.value
                    return newState
                })
            }
        

        【讨论】:

        • 它没有回答我的问题,但我喜欢代码的简洁性。
        • 您正在过滤 newState 并返回 newState,过滤器函数不会更改状态值它返回数组,因此您应该返回保存的值而不是 newState
        猜你喜欢
        • 2020-01-28
        • 2020-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-31
        • 1970-01-01
        • 2020-06-13
        • 2018-03-28
        相关资源
        最近更新 更多