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

Написал код, полностью работает так, как я задумал. Но вот вопрос, не могу понять почему он так работает?
Читать комент в коде.
/* 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.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы