【问题标题】:what stops React component from re-rendering是什么阻止了 React 组件重新渲染
【发布时间】:2018-07-19 17:22:54
【问题描述】:

我是新来的反应,我有一个问题。我有两个组件,父组件 - 目标和子组件 - EditGoal。目标组件渲染所有目标,结束 EditGoal 组件编辑目标的名称。在子组件完成修改后,它将数据保存在数据库中,并通过道具在父组件中执行一个函数。该函数设置状态。这应该会导致父组件重新渲染。但由于某种原因,父组件不会重新渲染。我不知道为什么。我想重新渲染父组件的原因是我可以获得一个包含更新的目标列表,这只是由一个孩子制作的。任何想法为什么父组件不重新渲染?或者我怎么能绕过它?我真的很感激任何建议!

目标组件:

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

import moment from 'moment';

class Goals extends Component {
  constructor(props) {
    super(props);

    this.state = {
      goals: [],
      editingGoalId: 0,
      update: 'false'
    };
    this.getGoals = this.getGoals.bind(this);
    this.populateGoals = this.populateGoals.bind(this);
    this.deleteGoal = this.deleteGoal.bind(this);
    this.editGoal = this.editGoal.bind(this);
    this.updateGoals = this.updateGoals.bind(this);
  }

  componentDidMount(){
    this.getGoals();
  }



  componentWillUpdate(nextProps, nextState){
console.log('will updated worked!')
  }

  getGoals() {
    $.ajax({
      url: `/api/v1/goals.json`,
      method: 'GET',
      success: this.populateGoals
    });
  }

  populateGoals(data) {
    this.setState({ goals: data.goals });
  }

  deleteGoal(goal) {
    $.ajax({
      url: `/api/v1/goals/${goal.id}`,
      method: 'DELETE'
    })
    .done((data) => {
      this.getGoals();
      console.log('Goal deleted!');

    })
    .fail((response) => {
      console.log.error('There was a problem deleting that goal.');
    });
  }

  editGoal(goal) {
    this.setState({ editingGoalId: goal.id })
  }

  updateGoals(name) {
  let goals = this.state.goals;

  goals = goals.map((currentGoal) =>{
    if(currentGoal.id == this.state.editingGoalId) {
      currentGoal.name = name;
    }
    return currentGoal;
  });

  this.setState({ goals: goals});

  console.log(this.state.goals);
  }

  render() {

    let goals = this.state.goals.map(goal => {
      if(this.state.editingGoalId === goal.id) {
        return(
          <EditGoal key={goal.id}
                    name={goal.name}
                    description={goal.description}
                    dueTime={moment(goal.due_time).format("MMMM Do YYYY, h:mm a")}
                    goal={goal}
                    update={this.updateGoals}
           />
          );
       } else {
         return(
          <Goal key={goal.id}
                name={goal.name}
                description={goal.description}
                startDate={moment(goal.created_at).format("MMMM Do YYYY, h:mm a")}
                dueTime={moment(goal.due_time).format("MMMM Do YYYY, h:mm a")}
                deadline={goal.due_time}
                goal={goal}
                onDelete={this.deleteGoal}
                onEdit={this.editGoal}
          />
          );
        }
    });
  return(
    <div>
      <h1>Goals</h1>
      <div>
        {goals}
      </div>
    </div>
    );
  }
}

export default Goals;

编辑目标组件:

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

class EditGoal extends Component {
  constructor(props){
    super(props);
    this.state = {
      updateGoalErrors: [],
      name: '',
      id: '',
      updatedDescription: '',
    }
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.getNameValue = this.getNameValue.bind(this);
  }

  componentDidMount() {
    this.getNameValue();
  }

  getNameValue(name) {
    this.setState({name: this.props.name});
    this.setState({id: this.props.goal.id});
  }

  handleChange(event) {
    this.setState({name: event.target.value })
  }

  handleSubmit(event){
    event.preventDefault();
    $.ajax({
      url: `/api/v1/goals/${this.state.id}`,
      method: 'PUT',
      dataType:'json',
      contentType: 'application/json',
      data: JSON.stringify({ name: this.state.name })
    })
    .done((data) => {
      if (data.errors) {
        this.setState({ updateGoalErrors: data.errors });
      } else {
        console.log("Goal updated in database")
        this.props.update(this.state.name);
      }
    });
  }

  render() {
    return(
      <form onSubmit={this.handleSubmit}>
        <div>
          <textarea value={this.state.name}
                    onChange={this.handleChange} />
        </div>
        <input type="submit" value="Save" />
      </form>
    );
  }
}

export default EditGoal;

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    在这里,我可以看到您在 componentDidMount 中编写了 ajax 调用,它将调用组件的第一个生命周期,在该编辑目标之后,您刚刚将状态 update 更新为 true,但不是列表目标。

    您可以调试它,在update 组件上的 setState 被重新渲染后,但是在将目标列表更新到数据库后,您还没有更新它。

    【讨论】:

    • 非常感谢。我添加了更新目标列表(添加目标的新名称)到状态的功能,但它并没有产生很大的不同。
    【解决方案2】:

    因此,像 Dipti Tiwari 所说,更新该州的目标列表确实有帮助。感谢那!另外我必须将editingGoalId设置为0,否则它会渲染子组件。

    updateGoals(name) {
     let goals = this.state.goals;
    
      goals = goals.map((currentGoal) =>{
        if(currentGoal.id == this.state.editingGoalId) {
          currentGoal.name = name;
        }
        return currentGoal;
      });
    
      this.setState({ goals: goals});
      this.setState({editingGoalId: 0 })
    
      console.log(this.state.goals);
      }
    

    自从我编写这段代码以来已经有一段时间了,所以我完全忘记了我在那里的那个 if 语句。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-20
      • 2020-07-06
      • 1970-01-01
      • 2020-08-14
      • 1970-01-01
      • 1970-01-01
      • 2018-10-07
      • 2021-06-19
      相关资源
      最近更新 更多