为什么我的父组件不重新渲染?

时间:2019-04-20 00:23:28

标签: reactjs redux react-redux

我有一个父组件,它呈现子组件列表。该列表来自redux存储。

在每个子组件中,我都有一个删除按钮,用于从redux存储中删除该特定项目,因此也删除了该子组件。

我的子级组件会从商店中删除该商品,所以为什么不重新渲染我的父级组件以将该子级从列表中删除?

我尝试在父组件中设置“刷新”本地状态,并尝试在子组件中进行切换,但是由于某些原因,该方法不起作用。

这是我的父组件:

class TodaysClasses extends Component {

  componentDidMount() {
    this.props.fetchTodayClasses('Tuesday')
  }

  renderClasses = (classes) => {
    if (classes.length > 0) {
      return classes.map((classRoom) => {
        return (
          <ClassComp classId={classRoom.id} key={classRoom.id}
            deleteClass={this.props.deleteClass}
          />
        )
      })
    } else {
      return <div>There are no classes for today.</div>
    }
  }

  render() {
    return (
      <div>
        <h3>Todays Classes</h3>
        <div className="ui divider"></div>
        <div className="ui grid container">
          <div className="row">
            {this.renderClasses(this.props.classes)}
          </div>
          <div className="row">
            <Link to="/newclass" className="ui labeled primary icon button">
              <i className="plus icon" />
              Add Class
            </Link>
          </div>
        </div>
      </div>
    )
  }
}

const mapStateToProps = state => {
  // turn the classes object to an array for easier iterations
  return { classes: Object.values(state.classes) }
}

export default connect(mapStateToProps, { fetchTodayClasses, deleteClass })(TodaysClasses)

这是我的孩子部分:

const ClassComp = (props) => {
  const { teacher, subject, students, id } = props.classOf

  return (
    <div className="ui segment" >
      <div className="content">
        <div className="ui medium header">{teacher} - {subject}</div>
        <div className="ui divider"></div>
        <div className="ui sub header">Students</div>
        <div>{renderStudents(students)}</div>
        <div style={{ marginBottom: '30px' }}>
          <button className="mini compact ui negative right floated button"
            onClick={() => props.deleteClass(id)}>Delete Class
          </button>
          <button className="mini compact ui right floated button">Edit Class</button>
        </div>

      </div>
    </div >
  )
}


const renderStudents = (students) => {
  if (students && students.length > 0) {
    return (
      <ol>
        {students.map((student, index) =>
          <li key={index}>{student}</li>
        )}
      </ol>
    )
  } else {
    return <p style={{ margin: '10px' }} >No students registered.</p>
  }
}

const mapStateToProps = (state, ownProps) => {
  return { classOf: state.classes[ownProps.classId] }
}

export default connect(mapStateToProps)(ClassComp)

这是我的动作创作者:

export const fetchTodayClasses = day => async dispatch => {
  const response = await classes.get(`/classes?day=${day}`)

  dispatch({ type: 'FETCH_TODAYCLASSES', payload: response.data })
}

export const deleteClass = id => async dispatch => {
  await classes.delete(`/classes/${id}`)

  dispatch({ type: 'DELETE_CLASS', payload: id })
}

这是我的减速器:

export default (state = {}, action) => {
  switch (action.type) {    
    case 'DELETE-CLASS':
      return _.omit(state, action.payload)
    case 'FETCH_TODAYCLASSES':
      return { ...state, ..._.mapKeys(action.payload, 'id') }    
    default:
      return state
  }
}

1 个答案:

答案 0 :(得分:2)

删除项目时缺少步骤:

  1. 已调度DELETE-CLASS类型的动作
  2. 该物品被减速器删除
  3. 缺少步骤-使用新数据更新商店

您可以通过2种常见模式来实现它:

  1. 通过API调用获取新数组
    componentDidUpdated() {
        this.props.actions.fetchTodayClasses(DAY);
    }
    
  2. 更新化简器(redux mutation patterns)中的阵列
     case 'DELETE-CLASS':
       let updatedClasses = _.omit(state, action.payload);
       return { ...state, ..._.mapKeys(updatedClasses, 'id') }
    
    我认为这两个选项是react-redux中最常见的模式。您选中此SandBox观看演示。确保在状态结构中正确使用它。