onChange отслеживает ввод данных пользователем в компонент TextField из Office-UI-Fabric при каждом рендеринге и отображает неверный вывод

Я пытаюсь реализовать пользовательский интерфейс, в котором я ввожу пользовательский ввод через компонент TextField из Office-ui-fabric. Я использую onChange для мониторинга значения. Однако, когда я ввожу пользовательский ввод, скажем, число «100», я вижу функцию, отображаемую каждый раз, что, как я считаю, является функцией onChange, но после завершения ввода моего ввода я вижу только «10» в окне консоли.

Я попытался изменить onChange на Blur, как было предложено в старом сообщении stackoverflow, но когда я это делаю, я не вижу никаких консольных сообщений.

const [msg, setMsg] = React.useState("");
React.useEffect(()=>{
   vscode.postMessage(
     {
       command: 'setMsg',
       text: msg
     }
   );
},[msg])

return (
<div>
 <Stack>
   <Stack.Item grow>
   <Label style={{ color: 'white' }}>Enter number </Label>
   <TextField placeholder="Enter number of images" value={msg} onChange={event => { setMsg((event.target as HTMLInputElement).value); console.log(msg);test() }} /> 
   </Stack.Item>
   </Stack>
</div>
);

Я ожидаю, что если я введу число «100», я увижу «100» в журнале консоли. В настоящее время я вижу '10'. Это правильный способ реализовать эту функцию? Приветствуется новая реакция и офис -ui-fabric, и любая помощь приветствуется.


person novice_coder    schedule 06.09.2019    source источник
comment
Привет, novice_coder, проверьте мое решение и дайте мне знать, если оно поможет.   -  person ravibagul91    schedule 06.09.2019


Ответы (1)


setState в React равно async и требует некоторого времени для выполнения/обновления состояния.

Когда вы это сделаете,

onChange={event => { 
   setMsg((event.target as HTMLInputElement).value); 
   console.log(msg);
   test() 
}}

После setState вы пытаетесь получить доступ к состоянию, которое в результате даст вам только предыдущее состояние.

Чтобы увидеть реальный эффект, удалите этот console.log из onChange и используйте хук useEffect. Поскольку у вас уже есть useEffect, который будет выполняться при изменении msg, вам просто нужно добавить в него строку console.log(msg).

React.useEffect(()=>{
        console.log(msg); // Now you will get updated value every time.
        vscode.postMessage(
            {
                command: 'setMsg',
                text: msg
            }
        );
},[msg])
person ravibagul91    schedule 06.09.2019
comment
Спасибо ! Я попробовал ваше предложение, и оно работает. Единственная проблема заключается в том, что я ввожу значение в TextField, скажем, 1000, но я не сразу вижу журнал консоли. Я даю пользовательский ввод другому TextField, когда я вижу значение msg = 1000 в консоли. Является ли это побочным эффектом моей реализации? Есть ли лучший способ сделать это? - person novice_coder; 06.09.2019
comment
Здесь появляется массив зависимостей, поскольку вы предоставили массив зависимостей для useEffect, он будет работать только тогда, когда эта зависимость будет изменена. Для любого другого изменения ввода он не будет выполнять этот useEffect. Если вы хотите показывать значение состояния при каждом рендеринге, вы можете просто использовать useEffect без какой-либо зависимости, такой как useEffect(() =>{console.log(msg)}). Теперь это будет выполняться при любом изменении ввода. - person ravibagul91; 06.09.2019
comment
Вы можете добавить любое количество useEffect. - person ravibagul91; 06.09.2019
comment
@novice_coder, можете ли вы также указать шаги для этого Единственная проблема в том, что я ввожу значение в TextField, скажем, 1000, но я не сразу вижу журнал консоли. Я даю пользовательский ввод другому TextField, когда я вижу значение msg = 1000 в консоли. - person ravibagul91; 06.09.2019
comment
Спасибо вам за вашу помощь, но я понял проблему. Я ошибочно отслеживал функцию setMsg вместо msg в useEffect. - person novice_coder; 09.09.2019