为什么我的 render 方法被调用两次

Sag*_*gar 9 reactjs

在此输入图像描述我对反应和还原还很陌生。这对我来说是一个有点令人困惑的问题。有人可以解释一下为什么我的 searchTerm 状态值在每次输入更改后打印两次(渲染方法被调用两次)。我阅读了 React 并了解到,在每次状态更改时,都会调用 render,但在此调用的 render 会被调用两次?我理解错了吗?

应用程序.js

import React from 'react';
import Todos from './components/Todos';
import Header from './components/Header';

class App extends React.Component {
state = {
    searchTerm : '',
    todos: [{
    id: 1,
    completed: true,
    text: "I am number one"
    }, 
{
    id: 2,
    completed: false,
    text: "I am number two"
},
{
    id: 3,
    completed: false,
    text: "I am number three"
}]
}

markComplete = (id) => {
    this.setState({
    todos: this.state.todos.map(todo => {
        if (todo.id === id) {
        todo.completed = !todo.completed;
        }
        return todo;
    })
    });
}

deleteTo = (id) => {
    this.setState({
    todos: [...this.state.todos.filter(todo => todo.id!==id)]
    });
}

search = (evt) => {
    const value = evt.target.value;
    this.setState({
    searchTerm: value
    });
}

render() {
    return (
    <div>
        <Header />
        { console.log(this.state.searchTerm) }
        <input type="text" onChange = {this.search} />         
        <Todos todos = {this.state.todos} markComplete = {this.markComplete} deleteTo = {this.deleteTo}/>
    </div>
    );
}
}

export default App;
Run Code Online (Sandbox Code Playgroud)

Todos.js

import React, { Component } from 'react';
import TodoItem from './TodoItem';

class Todos extends Component {

render() {
    return this.props.todos.map((todo) => 
    <TodoItem key={todo.id} todo = {todo} markComplete = {this.props.markComplete} deleteTo={this.props.deleteTo}/>)
}
}

export default Todos;
Run Code Online (Sandbox Code Playgroud)

TodoItem.js

import React, { Component } from 'react';

class TodoItem extends Component {

getStyle = () => {
    return { textDecoration: this.props.todo.completed ? "line-through": "none" };
};

getButtonStyle = () => {
    return {
        backgroundColor: 'red',
        border: 'none',
        cursor: 'pointer',
        float: 'right',
        padding: '5px 10px',
        borderRadius: '50%'
    };
}

render() {
    const {id, text} = this.props.todo;

    return ( 
    <div style={this.getStyle()}>
        <p>
        <input type="checkbox" onChange= { () => this.props.markComplete(id) }/> {' '}
        {text} 
        <button style={this.getButtonStyle()} onClick = { () => this.props.deleteTo(id)}> x </button>
        </p>
    </div>
    );
}
}

export default TodoItem;
Run Code Online (Sandbox Code Playgroud)

小智 38

这可能是因为你的index.js文件中的React StrictMode(如果你使用create-react-app)。

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
serviceWorker.unregister();
Run Code Online (Sandbox Code Playgroud)

严格模式检查潜在问题并导致运行某些生命周期方法两次(例如构造函数、渲染、ComponentShouldUpdate 等)。

严格模式检查仅在开发模式下运行;它们不会影响生产构建。

你可以在严格模式上阅读更多相关内容


Dre*_*ese 5

在提交阶段发生并将更新刷新到 DOM 之前,该render函数几乎可以调用任意次数。渲染函数也应该是纯函数,这意味着没有副作用,例如控制台日志记录。相反,使用componentDidUpdate生命周期函数来记录状态或属性更新的时间。也许这张图会有所帮助。

在此输入图像描述