Почему мой родительский компонент не рендерится повторно? - PullRequest
2 голосов
/ 20 апреля 2019

У меня есть родительский компонент, который отображает список дочерних компонентов.Этот список взят из магазина редуксов.

В каждом дочернем компоненте у меня есть кнопка удаления, чтобы удалить этот конкретный элемент из хранилища и, следовательно, удалить этот дочерний компонент.

Мой дочерний компонент удаляет элемент из магазина нормально, так почему мои родительские компоненты не были повторно обработаны, чтобы удалить этот дочерний элемент из списка ??

Я пробовал установить«обновить» локальное состояние в родительском компоненте и попытаться переключить его в дочернем компоненте, но по какой-то причине это не сработало.

Вот мой родительский компонент:

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 Ответ

2 голосов
/ 22 апреля 2019

Вы пропускаете шаг при удалении элемента:

  1. Отправлено действие типа DELETE-CLASS
  2. элемент удаляется редуктором
  3. отсутствует шаг - обновить магазин новыми данными

Вы можете достичь этого с помощью 2 общих схем:

  1. Получить новый массив с помощью вызова API
    componentDidUpdated() {
        this.props.actions.fetchTodayClasses(DAY);
    }
    
  2. Обновление массива в редукторе ( шаблоны редукционных мутаций )
     case 'DELETE-CLASS':
       let updatedClasses = _.omit(state, action.payload);
       return { ...state, ..._.mapKeys(updatedClasses, 'id') }
    
    Я думаю, что эти два варианта являются наиболее распространенными в реакторе-редуксе. Вы проверяете этот SandBox , чтобы посмотреть демонстрацию. Убедитесь, что вы используете его правильно со своей структурой состояния.
...