Использование ссылок с условным рендерингом - PullRequest
0 голосов
/ 23 июня 2018

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

class App extends React.Component {
  textInput
  constructor(props) {
    super(props)
    this.state = {isEditing: false}
    this.textInput = React.createRef()
  }

    onClick = () => {
        this.setState({isEditing: !this.state.isEditing})
        this.textInput.current.focus();
    }
  render () {
    let edit = this.state.isEditing ?
        (<input type="text" ref={this.textInput} />)
        : ""
    return (
      <div>
            <button onClick={this.onClick}>lorem </button>
            {edit}
      </div>
    );
  }
}

Когда я нажимаю на кнопку, отображается тег ввода, но ссылка textInput по-прежнему установлена ​​на null.Таким образом, я не могу сфокусировать ввод.

Я нашел какой-то обходной путь, например:

  • set autoFocus свойство во входном теге
  • скрыть входной тег с помощьюcss когда isEditing == false

Но на самом деле это очень простой шаблон, и я хотел бы знать, есть ли чистое решение.

Спасибо

Ответы [ 2 ]

0 голосов
/ 16 июня 2019

Большое спасибо за ваш ответ @rossipedia.Мне было интересно, смогу ли я сделать это с помощью хуков.

И, очевидно, вы не можете передать второй параметр для использования установщика состояния, как в setState.Но вы можете использовать useEffect следующим образом (обратите внимание на второй параметр в useEffect):

const [isEditing, setIsEditing] = React.useState(false);
React.useEffect(() => {
    if (isEditing) {
        textInput.current.focus();
    }
}, [isEditing]);

const handleClick = () => setIsEditing(isEditing);

И это сработало!;)

Источник: https://www.robinwieruch.de/react-usestate-callback/

0 голосов
/ 23 июня 2018

TL; DR:

Измените это:

this.setState({isEditing: !this.state.isEditing})
this.textInput.current.focus();

на это:

this.setState(state => ({isEditing: !state.isEditing}), () => {
    this.textInput.current.focus();    
});

Подробности:

Вы столкнулись собщая проблема, с которой многие сталкиваются в React, - это предположение, что состояние установки является синхронным.Это не.Когда вы вызываете setState, вы запрашиваете , чтобы React обновил состояние.Фактическое обновление состояния происходит позже.Это означает, что сразу после вызова setState элемент edit еще не был создан или визуализирован, поэтому ссылка указывает на null.

From docs :

setState() ставит в очередь изменения состояния компонента и сообщает React, что этот компонент и его дочерние элементы необходимо повторно визуализировать с обновленным состоянием.Это основной метод, используемый вами для обновления пользовательского интерфейса в ответ на обработчики событий и ответы сервера.

Думайте о setState() как о запросе, а не как о немедленной команде для обновления компонента.Для лучшего восприятия производительности React может задержать ее, а затем обновить несколько компонентов за один проход.React не гарантирует, что изменения состояния будут применены немедленно.

setState() не всегда сразу обновляет компонент.Это может пакетировать или отложить обновление до позже.Это делает чтение this.state сразу после вызова setState() потенциальной ошибкой.Вместо этого используйте componentDidUpdate или setState callback (setState(updater, callback)), который гарантированно сработает после применения обновления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...