Предупреждение: findDOMNode устарел в StrictMode. findDOMNode был передан экземпляр Transition, который находится внутри StrictMode

Я пытаюсь использовать функцию в качестве опоры внутри компонента, и этот компонент является дочерним по отношению к другому компоненту. Но функция не работает.? Могу я узнать почему. Это предупреждение, которое я получаю в консоли.

Предупреждение: findDOMNode устарел в StrictMode. findDOMNode был передан экземпляр Transition, который находится внутри StrictMode. Вместо этого добавьте ссылку прямо к элементу, на который вы хотите сослаться.

Это мой код

class Todo extends Component {
  state = {
    show: false,
    editTodo: {
      id: "",
      title: "",
      isCompleted: false
    }
  }
  handleClose = () => {
    this.setState({ show: false })
  }
  handleShow = () => {
    this.setState({ show: true })
  }
  getStyle () {
    return {
      background: '#f4f4f4',
      padding: '10px',
      borderBottom: '1px #ccc dotted',
      textDecoration: this.props.todo.isCompleted ? 'line-through'
        : 'none'
    }
  }
  //this method checks for changes in the edit field
  handleChange = (event) => {
    this.setState({ title: event.target.value })
    console.log(this.state.editTodo.title);
  }

  render () {
    //destructuring
    const { id, title } = this.props.todo;
    return (
      <div style={this.getStyle()}>
        <p>
          <input type='checkbox' style={{ margin: "0px 20px" }} onChange={this.props.markComplete.bind(this, id)} /> {''}
          {title}
          <Button style={{ float: "right", margin: "0px 10px" }} variant="warning" size={"sm"} onClick={this.handleShow}>Edit</Button>{' '}
          <Button style={{ float: "right" }} variant="danger" size={"sm"} onClick={this.props.DelItem.bind(this, id)}>Delete</Button>
        </p>
        <Modal show={this.state.show} onHide={this.handleClose}>
          <Modal.Header closeButton>
            <Modal.Title>Edit your Task!</Modal.Title>
          </Modal.Header>
          <Modal.Body >
            <FormGroup >
              <Form.Control
                type="text"
                value={this.state.editTodo.title}
                onChange={this.handleChange}
              />
            </FormGroup>
          </Modal.Body>
          <Modal.Footer>
            <Button variant="secondary" onClick={this.handleClose}>
              Close
                          </Button>
            <Button variant="primary" onClick={this.handleClose}>
              Save Changes
                          </Button>
          </Modal.Footer>
        </Modal>
      </div>
    )

  }
}

person Niroshan_Krish    schedule 28.03.2020    source источник
comment
Ошибка findDOMNode выглядит так, как будто она происходит внутри библиотеки, а не в вашем коде. Я не думаю, что это предупреждение для вашей проблемы. Какая часть написанного вами кода не работает должным образом?   -  person Ross Allen    schedule 28.03.2020
comment
метод handleChange не работает так, как я ожидал   -  person Niroshan_Krish    schedule 28.03.2020


Ответы (10)


Вызов setState выглядит так, как будто он записывается не в то место. Убедитесь, что он находится на объекте editTodo:

    handleChange = (event) => {
        this.setState(state => ({
          editTodo: {
            ...state.editTodo,
            title: event.target.value,
          },
        }));
    }
person Ross Allen    schedule 28.03.2020
comment
танкс человек. Это частично решает мою проблему. Теперь я могу получить ожидаемый результат от функции. Но предупреждение все еще есть. В любом случае спасибо !. - person Niroshan_Krish; 28.03.2020
comment
Вам не стоит беспокоиться об этом предупреждении. Я предполагаю, что он исходит из любой библиотеки, которую вы используете для компонентов Modal и Button (может быть, response-bootstrap?). Это предупреждение о том, что эта функция устарела, но это означает, что она по-прежнему работает нормально, но будет удалена в следующем выпуске React. - person Ross Allen; 28.03.2020
comment
@RossAllen css-transtion из react-transition-group создать такое же предупреждение - person Mhmdrz_A; 02.05.2020
comment
Ответ действительно не имеет ничего общего с вопросом, заданным в заголовке, ваш комментарий гораздо более подходит в качестве ответа, и ответ гораздо более подходит в качестве комментария IMHO. - person Silidrone; 25.06.2021

В index.js измените <React.StrictMode><App /><React.StrictMode> на <App />, и вы не увидите это предупреждение. Обратите внимание, что строгий режим помогает вам с

  • Выявление компонентов с небезопасным жизненным циклом
  • Предупреждение об использовании устаревшего API строки ref
  • Предупреждение об устаревшем использовании findDOMNode
  • Обнаружение неожиданных побочных эффектов
  • Обнаружение устаревшего API контекста

Перед удаление его.

person Ali Rehman    schedule 05.07.2020
comment
Лучше исправить основную причину - person java-addict301; 20.08.2020
comment
как исправить эту первопричину? - person Ankit Kumar; 22.08.2020
comment
Полезное решение, когда предупреждение исходит от сторонних библиотек. - person Alcides Bezerra; 26.03.2021

Если вы используете модальное окно или карусель из react-bootstrap, временным решением является отключение анимации. При их выключении предупреждение исчезает.

Для модальных окон:

<Modal animation={false}>
    <Modal.Header closeButton>
        <Modal.Title>Title</Modal.Title>
    </Modal.Header>
    <Modal.Body>
        Content
    </Modal.Body>
</Modal>

Для каруселей:

<Carousel slide={false} fade={false}>
    <Carousel.Item>
      Scene 1
    </Carousel.Item>
    <Carousel.Item>
      Scene 2
    </Carousel.Item>
</Carousel>

Я знаю, что он лучше подходит в качестве комментария, если он не отвечает на вопрос OP, но у меня недостаточно репутации, чтобы сделать это, и, возможно, это кому-то поможет.

person Francisco Gomes    schedule 12.10.2020
comment
Просто примечание: предупреждение исчезает, когда вы запускаете собранную версию. - person Francisco Gomes; 18.11.2020
comment
И если вы используете OverlayTrigger из реактивного загрузчика, установка transition={false} поможет. - person Drunken Daddy; 19.12.2020
comment
Еще одно примечание: если у вас есть несколько модальных окон response-bootstrap на одной странице, все должны иметь anmiation = {false} - person karpy47; 31.05.2021
comment
Это должен быть принятый ответ. - person Silidrone; 25.06.2021

Ответ @Ross Allen не имеет отношения к основной проблеме (предупреждению), он решил проблему синтаксиса в коде.

Ответ @Ali Rehman больше связан с предупреждением, но он также не решает правильно проблему, он только скрывает проблему, чтобы предупреждение больше не появлялось. .. Почему бы и нет, если нас не волнуют устаревания !!

Да, проблема исходит из React.StrictMode:

<React.StrictMode>
 <App />
</React.StrictMode>

StrictMode - это инструмент для выделения потенциальных проблем в приложении. Он активирует дополнительные проверки и предупреждения для своих потомков, например:

  • Выявление компонентов с небезопасным жизненным циклом
  • Предупреждение об использовании устаревшего API строки ref
  • Предупреждение об устаревшем использовании findDOMNode
  • Обнаружение неожиданных побочных эффектов
  • Обнаружение устаревшего API контекста

Поскольку обратная трассировка ошибки не полностью указана в вопросе, я предполагаю, что проблема связана с предупреждением об устаревшем использовании findDOMNode из-за ссылки на элементы в методах рендеринга:

<Modal show={this.state.show} onHide={this.handleClose}>
      <Modal.Header closeButton>
        <Modal.Title>Edit your Task!</Modal.Title>
      </Modal.Header>
      <Modal.Body >
        <FormGroup >
          <Form.Control
            type="text"
            value={this.state.editTodo.title}
            onChange={this.handleChange}
          />
        </FormGroup>
      </Modal.Body>
      <Modal.Footer>
        <Button variant="secondary" onClick={this.handleClose}>
          Close
                      </Button>
        <Button variant="primary" onClick={this.handleClose}>
          Save Changes
                      </Button>
      </Modal.Footer>
    </Modal>

Когда компонент визуализируется, то есть модальное окно также было отрисовано, и мы пытаемся изменить состояния компонента, компонент (и, таким образом, модальный) будет повторно отрисован, и на этом этапе модальное окно не может иметь доступа к состояниям. .

Решение устранить предупреждение - использовать React refs. Refs помогает получить доступ к узлам DOM или элементам React, созданным в методе рендеринга.

person Ahmad MOUSSA    schedule 27.07.2020
comment
Не могли бы вы привести какой-нибудь пример? То, что вы сказали, имеет для меня смысл. Я попытался установить ref={myRef} на модальный режим и target={myRef} на кнопку, но все равно получаю предупреждение. Я использую функциональный компонент с крючками. Спасибо! - person Francisco Gomes; 14.10.2020
comment
братан, ты получил ответ? - person Anuragh KP; 22.12.2020

Я не уверен, помогает ли это при использовании библиотеки material-ui, но во многих случаях это может помочь:

const nodeRef = React.useRef(null);
return <div>
  <CSSTransition ... nodeRef={nodeRef}>
    <div ref={nodeRef}> ... </div>
  </CSSTransition>
</div>
person Eran Or    schedule 27.01.2021

Я видел эту ошибку раньше, когда использовал response-bootstrap и react-router-dom рядом друг с другом. я заменил

<Link to="/foo">sth</Link>

с участием

 <LinkContainer to="/foo/bar">
  <Button>Foo</Button>
</LinkContainer>

и нет необходимости использовать ссылку для NavLink

person afshar003    schedule 26.02.2021

Самое простое решение для этого типа сценария - обернуть ваш компонент элементом DOM, к которому вы можете прикрепить ссылку. Например:

import React, { createRef, Component } from "react";
import ChildComponent from "./child-component";

class MyComponent extends Component {

 componentDidMount() {
  const node = this.wrapper.current;
  /* Uses DOM node  */ 
}

wrapper = createRef();

render () {
return (
  <div ref={this.wrapper}>
    <ChildComponent>{this.props.children}</ChildComponent>
  </div>
 );
 }
}

export default MyComponent;`
person eljana    schedule 23.10.2020

Похожая проблема:

В функции ReactDOM.render() измените

из

  < React.StrictMode >
    < SnackbarProvider >
          <App/>
    < /SnackbarProvider >
  < /React.StrictMode >

to

  < SnackbarProvider >
    < React.StrictMode >
          <App/>
    < /React.StrictMode >
  < /SnackbarProvider >

ПРИМЕЧАНИЕ. Теги SnackbarProvider & React.StrictMode поменяны местами.

person Manohar Reddy Poreddy    schedule 20.02.2021

чтобы исправить это, просто сделайте это изменение в index.js из:

  ReactDOM.render(
   <React.StrictMode>
     <App />
  </React.StrictMode>,
  document.getElementById('root')
);

to

  ReactDOM.render(
    <App />,
    document.getElementById('root')
 );
person Asma_Kh    schedule 02.01.2021
comment
это не исправление. StrictMode - это инструмент для выявления потенциальных проблем в приложении. - person Ali Kleit; 09.01.2021

Чтобы решить эту проблему, просто удалите React.StrictMode из index.js, где вы получаете доступ к корневому идентификатору dom, который исправит его.

Вместо этого:

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

Используйте эту строку:

ReactDOM.render(<App />,document.getElementById('root'));
person Mohammed    schedule 10.01.2021