Почему отрабатывает это событие?

Написал код, полностью работает так, как я задумал. Но вот вопрос, не могу понять почему он так работает?
Читать комент в коде.
/* global $ */
import React, {Component}from 'react';
import PropTypes from 'prop-types';
import {connect}from 'react-redux';

class App extends Component {
	static PropTypes = {
		tracks: PropTypes.array.isRequired,
		onAddTrack: PropTypes.func,
		onFindTrack: PropTypes.func,
		onDeleteTreck: PropTypes.func,
	};

	constructor() {
		super();
		this.state = {track: {id: '', name: ''}};
	}

	addTrack() {
		const props = this.props;
		props.onAddTrack(this.trackInput.value);
		this.trackInput.value = '';
	}

	findTrack() {
		const props = this.props;
		props.onFindTrack(this.searchInput.value);
	}

	deleteTreck(id) {
		const props = this.props;
		props.onDeleteTreck(id);
	}

	openPopup(track) {
		const inst = $('[data-remodal-id=modal]').remodal();
		inst.open();
		this.setState({track: {id: track.id, name: track.name}});
	}

	handleChange(event) {
		const track = this.state.track;
		this.setState({track: {id: track.id, name: event.target.value}});
	}

	saveNewTrackName() {
		const props = this.props;
		const track = this.state.track;
		props.tracks.forEach(obj => {
			if (obj.id === track.id){
				obj.name = track.name;
			}
		});
		props.onChangeTrack(props.tracks);
		this.setState({});               если удалить эту строку то при закрытие popup'a в
                                               (при этом происходит сохранение нового названия в стор )
                                             в  сторе значение меняется а на странице нет .
                                              Получился какой-то костыль мне кажется, 
                                              a c этой строкой работает все хорошо 
	}

	render() {
		const props = this.props;
		console.log('props ', props);
		return (
			<div className='container'>
				<div>
					<input ref={input => {this.trackInput = input;}} type='text' />
					<button onClick={this.addTrack.bind(this)}>Add Track</button>
				</div>
				<div>
					<input ref={input => {this.searchInput = input;}} type='text' />
					<button onClick={this.findTrack.bind(this)}>Find Track</button>
				</div>
				<ul>
					{
						props.tracks.map((track, index) =>
							(
								<li key={index}>
									{track.name}
									<span className='delete-button' onClick={() => this.deleteTreck(track.id)} > <button>X</button></span>
									<button onClick={() => this.openPopup(track)} >редактировать</button>

								</li>
							)
						)
					}
				</ul>
				<div
					className='remodal'
					data-remodal-id='modal'
					data-remodal-options='hashTracking: false'
				>
					<button className='remodal-close' data-remodal-action='close' >X</button>
					<p>Отредактируй и сохрани</p>
					<input
						onChange={e => {this.handleChange(e);}}
						type='text'
						value={this.state.track.name}
					/>
					<button
						className='remodal-confirm'
						data-remodal-action='confirm'
						onClick={this.saveNewTrackName.bind(this)}
					>OK</button>
				</div>
			</div>
		);
	}

}

export default connect(
	state => ({
		tracks: state.tracks.filter(track => track.name.includes(state.filterTracks)),
	}),
	dispatch => ({
		onAddTrack: name => {
			const payload = {
				id: Date.now().toString(),
				name,
			};
			dispatch({type: 'ADD_TRACK', payload});
		},
		onDeleteTreck: trackId => {
			dispatch({type: 'DELETE_TRACK', payload: trackId});
		},
		onFindTrack: name => {
			dispatch({type: 'FIND_TRACK', payload: name});
		},
		onChangeTrack: tracks => {
			dispatch({type: 'CANGE_TRACK', tracks});
		},
	}),
)(App);

кусочек кода из стора
}else if (action.type === 'CANGE_TRACK'){
	return state;
}

Может вообще нужно по другому делать, а я не знаю ) .
  • Вопрос задан
  • 64 просмотра
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
Вы передаете в store.dispatch действие:
{type: 'CANGE_TRACK', tracks}
А store по нему не обновляется, так как вы просто прокидываете предыдущее состояние:
} else if (action.type === 'CANGE_TRACK'){
  return state;
}

Вызов:
this.setState({});
инициирует обновление компонента и изменения видно только потому, что вы мутируете props:
props.tracks.forEach(obj => {
  if (obj.id === track.id){
    obj.name = track.name;
  }
});

что неправильно.

Исправить можно так:
} else if (action.type === 'CANGE_TRACK'){
    return [
      ...state,
      action.payload,
    ];
}

Но вам обязательно надо исправить то место, где вы мутируете props.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
26 апр. 2024, в 06:46
1000 руб./в час
26 апр. 2024, в 05:31
1000 руб./за проект