警告:findDOMNode在StrictMode中已弃用。 findDOMNode传递了StrictMode内部的Transition实例

时间:2020-03-28 16:15:24

标签: javascript reactjs react-component react-state strict-mode

我正在尝试使用功能作为组件内部的支持,而该组件是另一个组件的子代。但是功能不起作用。我能知道为什么吗。这是我在控制台中收到的警告。

警告:findDOMNode在StrictMode中已弃用。 findDOMNode传递了StrictMode内部的Transition实例。相反,直接将引用添加到要引用的元素

这是我的代码

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

  }
}

11 个答案:

答案 0 :(得分:24)

在index.js中,将<React.StrictMode><App /><React.StrictMode>更改为<App />,您将不会看到此警告。请注意,严格模式可以帮助您

  • 识别具有不安全生命周期的组件
  • 有关旧式字符串引用API使用情况的警告
  • 有关过时的findDOMNode使用的警告
  • 检测出意外的副作用
  • 检测遗留上下文API

在删除之前,请先参阅https://reactjs.org/docs/strict-mode.html

答案 1 :(得分:11)

@Ross Allen的响应与基本问题(警告)无关,它解决了代码中的语法问题。

@Ali Rehman的响应与警告更相关,但是也不能正确地解决 问题,它只会隐藏问题,因此警告不会不再出现..如果我们不在乎弃用的话,为什么不呢!

是的,问题出在React.StrictMode:

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

StrictMode是用于突出显示应用程序中潜在问题的工具。它为后代激活其他检查和警告,例如:

  • 识别具有不安全生命周期的组件
  • 有关旧式字符串引用API使用情况的警告
  • 有关过时的findDOMNode使用的警告
  • 检测出意外的副作用
  • 检测遗留上下文API

由于错误回溯没有在问题中完全给出,我认为问题与有关findDOMNode使用已过时的警告有关,因为它引用了render方法中的元素:

<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。引用有助于访问在render方法中创建的DOM节点或React元素。

答案 2 :(得分:9)

setState调用看起来好像被写到了错误的位置。确保它在editTodo对象上:

    handleChange = (event) => {
        this.setState(state => ({
          editTodo: {
            ...state.editTodo,
            title: event.target.value,
          },
        }));
    }

答案 3 :(得分:9)

如果您使用的是react-bootstrap中的Modal或Carousel,一种变通办法是禁用动画。关闭它们会使警告消失。

对于模式:

<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问题,它会更适合作为评论,但是我没有足够的声誉来做到这一点,也许对某人有所帮助。

答案 4 :(得分:6)

我不确定它在使用 material-ui 库时是否有帮助,但在许多情况下这会有所帮助:

const nodeRef = React.useRef(null);
return <div>
  <CSSTransition ... nodeRef={nodeRef}>
    <div ref={nodeRef}> ... </div>
  </CSSTransition>
</div>

答案 5 :(得分:1)

我以前见过这个错误,当我同时使用 react-bootstrap 和 react-router-dom 时 彼此 。 我换了

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

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

并且无需为 NavLink 使用 Link

答案 6 :(得分:0)

问题:在您的实现中,它是从下面的某个地方出现的:

mount = createMount({strict: true});

修复:应如下所示:

mount = createMount(); // by default, it is false

检查一下,确认安装正确。

答案 7 :(得分:0)

这种情况的最简单解决方案是用DOM元素包装您的组件,您实际上可以将引用附加到该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;`

答案 8 :(得分:0)

要解决此问题,只需从访问 dom 根 ID 的 index.js 中删除 React.StrictMode,即可解决此问题。

取而代之的是:

        public QuizResultaat Post([FromBody] IEnumerable<QuizAntwoord> antwoorden)
        {
            int aantalJuisteAntwoorden = 0;

            foreach (QuizAntwoord antwoord in antwoorden)
            {
                QuizVraag vraag = _vragen
                    .FirstOrDefault(v => v.Id == antwoord.VraagId);

                if (vraag.JuisteAntwoordIndex == antwoord.GekozenAntwoordIndex)
                {
                    aantalJuisteAntwoorden++;
                }
            }
            float scorePercentage = ((float)aantalJuisteAntwoorden / (float)_vragen.Count) * 100;

            return new QuizResultaat()
            {
                Percentage = scorePercentage
            };
        }

使用这一行:

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

答案 9 :(得分:0)

类似的问题:

ReactDOM.render() 函数中,更改

来自

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

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

注意:SnackbarProviderReact.StrictMode 标签是颠倒的。

答案 10 :(得分:-1)

要解决此问题,只需在 index.js 中进行以下更改:

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

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