Перейти к содержимому


Как исправить ошибку в своей реализации redux?

javascript react

  • Вы не можете ответить в тему
В этой теме нет ответов

#1 s24344

    Продвинутый пользователь

  • Пользователи
  • PipPipPip
  • 45 сообщений
Репутация: 0

Отправлено 11 Август 2019 - 11:03

Всем привет. У меня не есть самостоятельная реализация redux (разбираюсь с чужим кодом). И у меня возникла следующая проблема.
import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
// Начну по порядку. Ниже приведены функции createStore, connect, Provider
const createStore = (reducer, initialState) => {
  let currentState = initialState
  const listeners = []
  const getState = () => currentState
  const dispatch = action => {
	currentState = reducer(currentState, action)
	listeners.forEach(listener => listener())
  }
  const subscribe = listener => listeners.push(listener)
  return { getState, dispatch, subscribe }
}
const connect = (mapStateToProps, mapDispatchToProps) =>
  Component => {
	class WrappedComponent extends React.Component {
	  render() {
		return (
		  <Component
			{...this.props}
			{...mapStateToProps(this.context.store.getState(), this.props)}
			{...mapDispatchToProps(this.context.store.dispatch, this.props)}
		  />
		)
	  }
	  componentDidUpdate() {
		console.log('componentDidUpdate()')
		this.context.store.subscribe(this.handleChange)
	  }
	  handleChange = () => {
		console.log('handleChange')
		this.forceUpdate()
	  }
	}
	WrappedComponent.contextTypes = {
	  store: PropTypes.object,
	}
	return WrappedComponent
  }
class Provider extends React.Component {
  getChildContext() {
	return {
	  store: this.props.store,
	}
  }
  render() {
	return React.Children.only(this.props.children)
  }
}
Provider.childContextTypes = {
  store: PropTypes.object,
}
// Ниже приведены actions, action creators, reducers
// actions
const CHANGE_INTERVAL = 'CHANGE_INTERVAL'
// action creators
const changeInterval = value => ({
  type: CHANGE_INTERVAL,
  payload: value,
})
// reducers
const reducer = (state, action) => {
  switch(action.type) {
	case CHANGE_INTERVAL:
	  return {
		...state,
		currentInterval: state.currentInterval + action.payload
	  }
	default:
	  return state
  }
}
// Далее компонент, которые будет отрендерен
class IntervalComponent extends React.Component {
  render() {
	console.log('render()')
	console.log(this.props)
	return (
	  <div>
		<span>Интервал обновления секундомера: {this.props.currentInterval} сек.</span>
		<span>
		  <button onClick={() => this.props.changeInterval(-1)}>-</button>
		  <button onClick={() => this.props.changeInterval(1)}>+</button>
		</span>
	  </div>
	)
  }
}
const Interval = connect((state) => ({
	currentInterval: state,
	// currentInterval: state.currentInterval,
  }),
  dispatch => ({
	changeInterval: value => dispatch(changeInterval(value))
  }))(IntervalComponent)

// init
ReactDOM.render(
  <Provider store={createStore(reducer)}>
	<Interval />
  </Provider>,
  document.getElementById('root')
)
В данном примере очевидная проблема, что не передается initialState
Что сделал я: в reducer дописал: state = initialState, ну и конечно описал initialState
const initialState = {
  currentInterval: 3000
}
// reducers
const reducer = (state = initialState, action) => {
  console.log('state', state)
  console.log('action', action)
  switch(action.type) {
	case CHANGE_INTERVAL:
	  return {
		...state,
		currentInterval: state.currentInterval + action.payload
	  }
	default:
	  return state
  }
}
Остались две проблемы:
- initialState нет при инициализации компонента
- И когда reducer обновляет состояние, не происходит render IntervalComponent, соответственно визуально ничего не меняется.
Буду благодарен любой помощи.


Если даже написать action для получения данных при инициализации компонента, то не происходит вызова render в компоненте при изменении store:
codepen.io/gsdev99/pen/pYqmRr

Сообщение отредактировал Rohviktor: 12 Август 2019 - 05:48






Количество пользователей, читающих эту тему: 1

0 пользователей, 1 гостей, 0 анонимных