反应状态不更新输入变化

react state not updating on input change

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

试试这个

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

您返回的是 newState 而不是 currentAnswer。

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

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

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

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

您似乎认为 currentAnswer 以某种方式与 newState 共享引用,但事实并非如此。每当您 运行 mapfindfilterreduce 时,您将获得数组的新副本,因此不会有 link 在 2.

之间

这里一个不错的选择是只映射状态

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